[Libreoffice-commits] core.git: 3 commits - include/vcl vcl/Library_vcl.mk vcl/source

Michael Meeks michael.meeks at collabora.com
Thu May 22 01:48:01 PDT 2014


 include/vcl/debugevent.hxx       |   36 ++++
 include/vcl/window.hxx           |    3 
 vcl/Library_vcl.mk               |    1 
 vcl/source/app/svmain.cxx        |    5 
 vcl/source/window/debugevent.cxx |  281 +++++++++++++++++++++++++++++++++++++++
 vcl/source/window/window.cxx     |   12 +
 6 files changed, 338 insertions(+)

New commits:
commit 344dc7fd0684acc31f4c18e99e65bfa6700c9c64
Author: Michael Meeks <michael.meeks at collabora.com>
Date:   Thu May 8 21:59:45 2014 +0100

    Make the inserted text more European and sensible for now.
    
    Change-Id: I8b2ecef11362c0fc1dc2b76780140881e769bb89

diff --git a/include/vcl/debugevent.hxx b/include/vcl/debugevent.hxx
index ce31570..2700324 100644
--- a/include/vcl/debugevent.hxx
+++ b/include/vcl/debugevent.hxx
@@ -20,7 +20,7 @@ class VCL_DLLPUBLIC DebugEventInjector : Timer {
   DebugEventInjector( sal_uInt32 nMaxEvents );
 
   Window *ChooseWindow();
-  void InjectKeyEvent();
+  void InjectTextEvent();
   void InjectMenuEvent();
   void InjectMouseEvent();
   void InjectEvent();
diff --git a/vcl/source/window/debugevent.cxx b/vcl/source/window/debugevent.cxx
index 37ca716..e83909e 100644
--- a/vcl/source/window/debugevent.cxx
+++ b/vcl/source/window/debugevent.cxx
@@ -7,7 +7,7 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  */
 
-#include <stdio.h>
+// #include <stdio.h>
 #include <rtl/math.hxx>
 #include <rtl/string.hxx>
 #include <tools/time.hxx>
@@ -110,11 +110,11 @@ void DebugEventInjector::InjectMenuEvent()
     SalMenuEvent aEvent = aIds[ getRandom() * aIds.size() ];
     bool bHandled = ImplWindowFrameProc( pSysWin, NULL, nEvent, &aEvent);
 
-    fprintf( stderr, "Injected menu event %p (%d) '%s' -> %d\n",
+/*    fprintf( stderr, "Injected menu event %p (%d) '%s' -> %d\n",
              aEvent.mpMenu, aEvent.mnId,
              OUStringToOString( ((Menu *)aEvent.mpMenu)->GetItemText( aEvent.mnId ),
                                 RTL_TEXTENCODING_UTF8 ).getStr(),
-             (int)bHandled);
+             (int)bHandled); */
 }
 
 static void InitKeyEvent( SalKeyEvent &rKeyEvent )
@@ -131,22 +131,43 @@ static void InitKeyEvent( SalKeyEvent &rKeyEvent )
         rKeyEvent.mnRepeat = 0;
 }
 
-void DebugEventInjector::InjectKeyEvent()
+void DebugEventInjector::InjectTextEvent()
 {
     SalKeyEvent aKeyEvent;
     Window *pWindow = ChooseWindow();
 
     InitKeyEvent( aKeyEvent );
-    sal_uInt16 nCode = getRandom() * KEY_CODE;
-    if( getRandom() < 0.05 ) // modifier
-        nCode |= (sal_uInt16)( getRandom() * KEY_MODTYPE ) & KEY_MODTYPE;
 
-    aKeyEvent.mnCode = nCode;
-    aKeyEvent.mnCharCode = getRandom() * 0xffff;
+    if (getRandom() < 0.10) // Occasionally a truly random event
+    {
+        aKeyEvent.mnCode = getRandom() * KEY_CODE;
+        aKeyEvent.mnCharCode = getRandom() * 0xffff;
+    }
+    else
+    {
+        struct {
+            sal_uInt16 nCodeStart, nCodeEnd;
+            char       aCharStart;
+        } nTextCodes[] = {
+            { KEY_0, KEY_9, '0' },
+            { KEY_A, KEY_Z, 'a' }
+        };
+
+        size_t i = getRandom() * SAL_N_ELEMENTS( nTextCodes );
+        int offset = trunc( getRandom() * ( nTextCodes[i].nCodeEnd - nTextCodes[i].nCodeStart ) );
+        aKeyEvent.mnCode = nTextCodes[i].nCodeStart + offset;
+        aKeyEvent.mnCharCode = nTextCodes[i].aCharStart + offset;
+//        fprintf( stderr, "Char '%c' offset %d into record %d base '%c'\n",
+//                 aKeyEvent.mnCharCode, offset, (int)i, nTextCodes[i].aCharStart );
+    }
+
+    if( getRandom() < 0.05 ) // modifier
+        aKeyEvent.mnCode |= (sal_uInt16)( getRandom() * KEY_MODTYPE ) & KEY_MODTYPE;
 
     bool bHandled = ImplWindowFrameProc( pWindow, NULL, SALEVENT_KEYINPUT, &aKeyEvent);
-    fprintf (stderr, "Injected key 0x%x -> %d win %p\n",
-             (int) aKeyEvent.mnCode, (int)bHandled, pWindow);
+//    fprintf( stderr, "Injected key 0x%x -> %d win %p\n",
+//             (int) aKeyEvent.mnCode, (int)bHandled, pWindow );
+    ImplWindowFrameProc( pWindow, NULL, SALEVENT_KEYUP, &aKeyEvent );
 }
 
 /*
@@ -155,12 +176,14 @@ void DebugEventInjector::InjectKeyEvent()
  */
 void DebugEventInjector::InjectEvent()
 {
+//    fprintf( stderr, "%6d - ", (int)mnEventsLeft );
+
     double nRand = getRandom();
-    if (nRand < 0.50)
+    if (nRand < 0.30)
     {
         int nEvents = getRandom() * 10;
         for (int i = 0; i < nEvents; i++)
-            InjectKeyEvent();
+            InjectTextEvent();
     }
     else if (nRand < 0.60)
         InjectKeyNavEdit();
@@ -222,8 +245,8 @@ void DebugEventInjector::InjectKeyNavEdit()
     aKeyEvent.mnCharCode = 0x0; // hopefully unused.
 
     bool bHandled = ImplWindowFrameProc( pWindow, NULL, SALEVENT_KEYINPUT, &aKeyEvent );
-    fprintf( stderr, "Injected edit / move key 0x%x -> %d win %p\n",
-             (int) aKeyEvent.mnCode, (int)bHandled, pWindow );
+//    fprintf( stderr, "Injected edit / move key 0x%x -> %d win %p\n",
+//             (int) aKeyEvent.mnCode, (int)bHandled, pWindow );
     ImplWindowFrameProc( pWindow, NULL, SALEVENT_KEYUP, &aKeyEvent );
 }
 
commit 45935fc3fed0a215e93de20c28933bf318f618cd
Author: Michael Meeks <michael.meeks at collabora.com>
Date:   Thu May 8 21:43:46 2014 +0100

    quit after emitting all the events to allow valgrinding.
    
    Change-Id: Ibee9d8f00008dd0a266db276772d48deb0bd9d18

diff --git a/vcl/source/window/debugevent.cxx b/vcl/source/window/debugevent.cxx
index 2f37678..37ca716 100644
--- a/vcl/source/window/debugevent.cxx
+++ b/vcl/source/window/debugevent.cxx
@@ -120,7 +120,7 @@ void DebugEventInjector::InjectMenuEvent()
 static void InitKeyEvent( SalKeyEvent &rKeyEvent )
 {
     double nRand = getRandom();
-    if (nRand < 0.01)
+    if (nRand < 0.001)
         rKeyEvent.mnTime = getRandom() * ULONG_MAX;
     else
         rKeyEvent.mnTime = Time::GetSystemTicks();
@@ -216,14 +216,15 @@ void DebugEventInjector::InjectKeyNavEdit()
     InitKeyEvent( aKeyEvent );
     aKeyEvent.mnCode = nKey;
 
-    if (getRandom() < 0.10) // modifier
+    if (getRandom() < 0.15) // modifier
         aKeyEvent.mnCode |= (sal_uInt16)(getRandom() * KEY_MODTYPE) & KEY_MODTYPE;
 
     aKeyEvent.mnCharCode = 0x0; // hopefully unused.
 
-    bool bHandled = ImplWindowFrameProc( pWindow, NULL, SALEVENT_KEYINPUT, &aKeyEvent);
-    fprintf (stderr, "Injected edit / move key 0x%x -> %d win %p\n",
-             (int) aKeyEvent.mnCode, (int)bHandled, pWindow);
+    bool bHandled = ImplWindowFrameProc( pWindow, NULL, SALEVENT_KEYINPUT, &aKeyEvent );
+    fprintf( stderr, "Injected edit / move key 0x%x -> %d win %p\n",
+             (int) aKeyEvent.mnCode, (int)bHandled, pWindow );
+    ImplWindowFrameProc( pWindow, NULL, SALEVENT_KEYUP, &aKeyEvent );
 }
 
 void DebugEventInjector::Timeout()
@@ -235,6 +236,8 @@ void DebugEventInjector::Timeout()
         SetTimeout( 1 );
         Start();
     }
+    else
+        Application::Quit();
 }
 
 DebugEventInjector *DebugEventInjector::getCreate()
commit 4ea70f09e964fd39b46941313493a11e131e21e1
Author: Michael Meeks <michael.meeks at collabora.com>
Date:   Thu May 8 17:03:08 2014 +0100

    Initial cut at some infinite monkeys work.
    
    Change-Id: I71c7fe027262305893d8eabee94a726f4aa909d6

diff --git a/include/vcl/debugevent.hxx b/include/vcl/debugevent.hxx
new file mode 100644
index 0000000..ce31570
--- /dev/null
+++ b/include/vcl/debugevent.hxx
@@ -0,0 +1,36 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#ifndef INCLUDED_VCL_DEBUGEVENT_HXX
+#define INCLUDED_VCL_DEBUGEVENT_HXX
+
+#include <vcl/dllapi.h>
+#include <vcl/timer.hxx>
+#include <sal/types.h>
+#include <vcl/window.hxx>
+
+class VCL_DLLPUBLIC DebugEventInjector : Timer {
+  sal_uInt32 mnEventsLeft;
+  DebugEventInjector( sal_uInt32 nMaxEvents );
+
+  Window *ChooseWindow();
+  void InjectKeyEvent();
+  void InjectMenuEvent();
+  void InjectMouseEvent();
+  void InjectEvent();
+  void InjectKeyNavEdit();
+  virtual void Timeout();
+
+  public:
+     static DebugEventInjector *getCreate();
+};
+
+#endif // INCLUDED_VCL_DEBUGEVENT_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/vcl/window.hxx b/include/vcl/window.hxx
index c9f8390..4576bdb 100644
--- a/include/vcl/window.hxx
+++ b/include/vcl/window.hxx
@@ -1029,6 +1029,9 @@ public:
     void                                SetData( void* pNewData );
     void*                               GetData() const;
 
+    /// Add all children to @rAllChildren recursively.
+    SAL_DLLPRIVATE void                 CollectChildren(::std::vector<Window *>& rAllChildren );
+
     void                                ShowFocus( const Rectangle& rRect );
     void                                HideFocus();
 
diff --git a/vcl/Library_vcl.mk b/vcl/Library_vcl.mk
index 4e53256..e321525 100644
--- a/vcl/Library_vcl.mk
+++ b/vcl/Library_vcl.mk
@@ -116,6 +116,7 @@ $(eval $(call gb_Library_add_exception_objects,vcl,\
     vcl/source/window/builder \
     vcl/source/window/cmdevt \
     vcl/source/window/cursor \
+    vcl/source/window/debugevent \
     vcl/source/window/decoview \
     vcl/source/window/dialog \
     vcl/source/window/dlgctrl \
diff --git a/vcl/source/app/svmain.cxx b/vcl/source/app/svmain.cxx
index f5b05fe..25c8f99 100644
--- a/vcl/source/app/svmain.cxx
+++ b/vcl/source/app/svmain.cxx
@@ -37,6 +37,7 @@
 #include "vcl/configsettings.hxx"
 #include "vcl/lazydelete.hxx"
 #include "vcl/embeddedfontshelper.hxx"
+#include "vcl/debugevent.hxx"
 
 #ifdef WNT
 #include <svsys.h>
@@ -288,6 +289,10 @@ bool InitVCL()
 
     DBGGUI_INIT_SOLARMUTEXCHECK();
 
+#if OSL_DEBUG_LEVEL > 0
+    DebugEventInjector::getCreate();
+#endif
+
     return true;
 }
 
diff --git a/vcl/source/window/debugevent.cxx b/vcl/source/window/debugevent.cxx
new file mode 100644
index 0000000..2f37678
--- /dev/null
+++ b/vcl/source/window/debugevent.cxx
@@ -0,0 +1,255 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <stdio.h>
+#include <rtl/math.hxx>
+#include <rtl/string.hxx>
+#include <tools/time.hxx>
+#include <vcl/keycodes.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/debugevent.hxx>
+#include <vcl/wrkwin.hxx>
+#include <vcl/menu.hxx>
+#include "window.h"
+#include "salwtype.hxx"
+
+#if OSL_DEBUG_LEVEL > 0
+
+DebugEventInjector::DebugEventInjector( sal_uInt32 nMaxEvents) :
+    mnEventsLeft( nMaxEvents )
+{
+    SetTimeout( 1000 /* ms */ );
+    Start();
+}
+
+static double getRandom()
+{
+    return (double)rand() / RAND_MAX;
+}
+
+Window *DebugEventInjector::ChooseWindow()
+{
+    Window *pWindow, *pParent;
+
+    if (getRandom() < 0.80 &&
+        (pWindow = Application::GetFocusWindow()))
+        return pWindow;
+
+    if (getRandom() > 0.50 ||
+        !(pParent = Application::GetActiveTopWindow()))
+    {
+        // select a top window at random
+        long nIdx = Application::GetTopWindowCount() * getRandom();
+        if (!(pParent = Application::GetTopWindow( nIdx )))
+            pParent = static_cast<Window *>(Application::GetAppWindow());
+    }
+    assert (pParent != NULL);
+
+    std::vector< Window *> aChildren;
+    pParent->CollectChildren( aChildren );
+
+    return aChildren[ aChildren.size() * getRandom() ];
+}
+
+void DebugEventInjector::InjectMouseEvent()
+{
+}
+
+typedef std::vector< SalMenuEvent > MenuItemIds;
+
+static void CollectMenuItemIds( Menu *pMenu, MenuItemIds &rIds )
+{
+    sal_uInt16 nItems = pMenu->GetItemCount();
+    for (sal_uInt16 i = 0; i < nItems; i++)
+    {
+        if (pMenu->GetItemType( i ) != MENUITEM_SEPARATOR || getRandom() < 0.01)
+            rIds.push_back( SalMenuEvent( pMenu->GetItemId( i ), pMenu ) );
+        PopupMenu *pPopup = pMenu->GetPopupMenu( i );
+        if (pPopup)
+            CollectMenuItemIds( pPopup, rIds );
+    }
+}
+
+void DebugEventInjector::InjectMenuEvent()
+{
+    Window *pFocus = Application::GetFocusWindow();
+    if (!pFocus)
+        return;
+
+    SystemWindow *pSysWin = pFocus->GetSystemWindow();
+    if (!pSysWin)
+        return;
+
+    MenuBar *pMenuBar = pSysWin->GetMenuBar();
+    if (!pMenuBar)
+        return;
+
+    sal_uInt16 nEvents[] = {
+        SALEVENT_MENUCOMMAND,
+        SALEVENT_MENUCOMMAND,
+        SALEVENT_MENUACTIVATE,
+        SALEVENT_MENUDEACTIVATE,
+        SALEVENT_MENUHIGHLIGHT,
+        SALEVENT_MENUCOMMAND,
+        SALEVENT_MENUCOMMAND,
+        SALEVENT_MENUCOMMAND,
+        SALEVENT_MENUBUTTONCOMMAND,
+        SALEVENT_MENUBUTTONCOMMAND,
+    };
+
+    MenuItemIds aIds;
+    CollectMenuItemIds( pMenuBar, aIds );
+
+    sal_uInt16 nEvent = nEvents[ (int)(getRandom() * SAL_N_ELEMENTS( nEvents )) ];
+    SalMenuEvent aEvent = aIds[ getRandom() * aIds.size() ];
+    bool bHandled = ImplWindowFrameProc( pSysWin, NULL, nEvent, &aEvent);
+
+    fprintf( stderr, "Injected menu event %p (%d) '%s' -> %d\n",
+             aEvent.mpMenu, aEvent.mnId,
+             OUStringToOString( ((Menu *)aEvent.mpMenu)->GetItemText( aEvent.mnId ),
+                                RTL_TEXTENCODING_UTF8 ).getStr(),
+             (int)bHandled);
+}
+
+static void InitKeyEvent( SalKeyEvent &rKeyEvent )
+{
+    double nRand = getRandom();
+    if (nRand < 0.01)
+        rKeyEvent.mnTime = getRandom() * ULONG_MAX;
+    else
+        rKeyEvent.mnTime = Time::GetSystemTicks();
+
+    if (getRandom() < 0.01)
+        rKeyEvent.mnRepeat = getRandom() * 20;
+    else
+        rKeyEvent.mnRepeat = 0;
+}
+
+void DebugEventInjector::InjectKeyEvent()
+{
+    SalKeyEvent aKeyEvent;
+    Window *pWindow = ChooseWindow();
+
+    InitKeyEvent( aKeyEvent );
+    sal_uInt16 nCode = getRandom() * KEY_CODE;
+    if( getRandom() < 0.05 ) // modifier
+        nCode |= (sal_uInt16)( getRandom() * KEY_MODTYPE ) & KEY_MODTYPE;
+
+    aKeyEvent.mnCode = nCode;
+    aKeyEvent.mnCharCode = getRandom() * 0xffff;
+
+    bool bHandled = ImplWindowFrameProc( pWindow, NULL, SALEVENT_KEYINPUT, &aKeyEvent);
+    fprintf (stderr, "Injected key 0x%x -> %d win %p\n",
+             (int) aKeyEvent.mnCode, (int)bHandled, pWindow);
+}
+
+/*
+ *   The more heuristics we have to inform this the better,
+ * key-bindings, menu entries, allowable entry types etc.
+ */
+void DebugEventInjector::InjectEvent()
+{
+    double nRand = getRandom();
+    if (nRand < 0.50)
+    {
+        int nEvents = getRandom() * 10;
+        for (int i = 0; i < nEvents; i++)
+            InjectKeyEvent();
+    }
+    else if (nRand < 0.60)
+        InjectKeyNavEdit();
+    else if (nRand < 0.95)
+        InjectMenuEvent();
+    else
+        InjectMouseEvent();
+}
+
+void DebugEventInjector::InjectKeyNavEdit()
+{
+    Window *pWindow = ChooseWindow();
+
+    struct {
+        double     mnProb;
+        sal_uInt16 mnKey;
+    } nWeights[] = {
+        // edit / escape etc. - 50%
+        { 0.20, KEY_SPACE },
+        { 0.10, KEY_TAB },
+        { 0.07, KEY_RETURN },
+        { 0.05, KEY_DELETE },
+        { 0.05, KEY_BACKSPACE },
+
+        // navigate - 45%
+        { 0.15, KEY_LEFT },
+        { 0.10, KEY_RIGHT },
+        { 0.05, KEY_UP },
+        { 0.05, KEY_DOWN },
+        { 0.05, KEY_PAGEUP },
+        { 0.05, KEY_PAGEDOWN },
+
+        // other
+        { 0.01, KEY_INSERT },
+        { 0.02, KEY_HOME },
+        { 0.02, KEY_END },
+    };
+
+    double d = 0.0, nRand = getRandom();
+    sal_uInt16 nKey = KEY_SPACE;
+    for ( size_t i = 0; i < SAL_N_ELEMENTS( nWeights ); ++i )
+    {
+        d += nWeights[i].mnProb;
+        assert (d < 1.01);
+        if ( nRand < d )
+        {
+            nKey = nWeights[i].mnKey;
+            break;
+        }
+    }
+
+    SalKeyEvent aKeyEvent;
+    InitKeyEvent( aKeyEvent );
+    aKeyEvent.mnCode = nKey;
+
+    if (getRandom() < 0.10) // modifier
+        aKeyEvent.mnCode |= (sal_uInt16)(getRandom() * KEY_MODTYPE) & KEY_MODTYPE;
+
+    aKeyEvent.mnCharCode = 0x0; // hopefully unused.
+
+    bool bHandled = ImplWindowFrameProc( pWindow, NULL, SALEVENT_KEYINPUT, &aKeyEvent);
+    fprintf (stderr, "Injected edit / move key 0x%x -> %d win %p\n",
+             (int) aKeyEvent.mnCode, (int)bHandled, pWindow);
+}
+
+void DebugEventInjector::Timeout()
+{
+    InjectEvent();
+    mnEventsLeft--;
+    if (mnEventsLeft > 0)
+    {
+        SetTimeout( 1 );
+        Start();
+    }
+}
+
+DebugEventInjector *DebugEventInjector::getCreate()
+{
+    sal_uInt32 nEvents;
+    const char *pEvents = getenv("VCL_EVENT_INJECTION");
+    if (!pEvents)
+        return NULL;
+    nEvents = OString( pEvents ).toUInt32();
+    if (nEvents > 0)
+        return new DebugEventInjector( nEvents );
+    else
+        return NULL;
+}
+
+#endif // OSL_DEBUG_LEVEL > 0
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/source/window/window.cxx b/vcl/source/window/window.cxx
index b77447c..849bce6 100644
--- a/vcl/source/window/window.cxx
+++ b/vcl/source/window/window.cxx
@@ -4727,6 +4727,18 @@ void Window::NotifyAllChildren( DataChangedEvent& rDCEvt )
     }
 }
 
+void Window::CollectChildren(::std::vector<Window *>& rAllChildren )
+{
+    rAllChildren.push_back( this );
+
+    Window* pChild = mpWindowImpl->mpFirstChild;
+    while ( pChild )
+    {
+        pChild->CollectChildren( rAllChildren );
+        pChild = pChild->mpWindowImpl->mpNext;
+    }
+}
+
 void Window::SetPointFont( const Font& rFont )
 {
 


More information about the Libreoffice-commits mailing list