]> git.saurik.com Git - wxWidgets.git/commitdiff
Merge wxUIActionSimulator fixes from SOC2010_GUI_TEST branch.
authorVadim Zeitlin <vadim@wxwidgets.org>
Sun, 22 Aug 2010 22:15:42 +0000 (22:15 +0000)
committerVadim Zeitlin <vadim@wxwidgets.org>
Sun, 22 Aug 2010 22:15:42 +0000 (22:15 +0000)
Correct a lot of problems with the initial implementation, notably make the
API consistent across all platforms, e.g. all keyboard-related methods now
take just a wxKeyCode.

Add some useful higher-level helpers such as Text() and MouseDragDrop().

Improve documentation.

wxUIActionSimulator now works under MSW, GTK and OS X and is enabled by
default.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@65385 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

22 files changed:
configure
configure.in
docs/changes.txt
docs/doxygen/mainpages/samples.h
include/wx/motif/setup0.h
include/wx/msw/setup0.h
include/wx/msw/wince/setup.h
include/wx/os2/setup0.h
include/wx/osx/setup0.h
include/wx/palmos/setup0.h
include/wx/setup_inc.h
include/wx/uiaction.h
include/wx/univ/setup0.h
include/wx/unix/utilsx11.h
include/wx/x11/privx.h
interface/wx/uiaction.h
samples/uiaction/uiaction.cpp
src/common/uiactioncmn.cpp
src/msw/uiaction.cpp
src/osx/uiaction_osx.cpp
src/unix/uiactionx11.cpp
src/unix/utilsx11.cpp

index e6e851bdd2b085ce2a72838e72a7eda28fc4f5cb..4dbc50888f8d7491d0d955987ceb97cb11fb6e7d 100755 (executable)
--- a/configure
+++ b/configure
@@ -2980,7 +2980,6 @@ DEFAULT_wxUSE_LIBSDL=no
 DEFAULT_wxUSE_ACCESSIBILITY=no
 DEFAULT_wxUSE_IPV6=no
 DEFAULT_wxUSE_GSTREAMER8=no
-DEFAULT_wxUSE_UIACTIONSIMULATOR=no
 
 DEFAULT_wxUSE_UNICODE_UTF8=auto
 DEFAULT_wxUSE_OPENGL=auto
index ff376e9cd14c3ddabeade417009746653077bd2e..0db87d3a53f6731b4142aa8a9d4cbd713d536b73 100644 (file)
@@ -387,7 +387,6 @@ dnl features disabled by default
 DEFAULT_wxUSE_ACCESSIBILITY=no
 DEFAULT_wxUSE_IPV6=no
 DEFAULT_wxUSE_GSTREAMER8=no
-DEFAULT_wxUSE_UIACTIONSIMULATOR=no
 
 dnl automatic features
 DEFAULT_wxUSE_UNICODE_UTF8=auto
index 7e831c5ba7dda4aba89071f5e54a0d682a54cb8a..2682b1940c55cfa1d7d2f8e6ff3672aa56af407d 100644 (file)
@@ -407,6 +407,7 @@ All (GUI):
 
 - Added wxRichMessageDialog (Rickard Westerlund, GSoC 2010 project).
 - Added wxCommandLinkButton (Rickard Westerlund, GSoC 2010 project).
+- Added wxUIActionSimulator (Steven Lamerton, GSoC 2010 project).
 - wxAUI: support auto-orientable toolbars (wsu).
 - Added wxDataViewCtrl::Set/GetCurrentItem().
 - wxHTML: render in RTL order inside RTL window (Richard Bullington-McGuire).
index 88dd1fa5978a3dbd412cec55472de376df4999b0..ae268507bcf20990be8723db1f0c46597af49f54 100644 (file)
@@ -131,6 +131,7 @@ TODO: Organize them in a more human-readable way.
 @li @sample{toolbar}
 @li @sample{treectrl}
 @li @sample{typetest}
+@li @sample{uiaction}
 @li @sample{validate}
 @li @sample{vscroll}
 @li @sample{widgets}
@@ -989,6 +990,17 @@ demonstrated here as well - try the corresponding menu entries.
 
 @sampledir{typetest}
 
+@section page_samples_uiaction wxUIActionSimulator Sample
+
+@sampleabout{wxUIActionSimulator}
+
+This sample shows some features of wxUIActionSimulator class. When a simulation
+is ran using its menu items, you can see that the button is pressed
+programmatically and the characters generated by the program appear in the text
+control.
+
+@sampledir{uiaction}
+
 @section page_samples_validate Validator Sample
 
 @sampleabout{wxValidator}
index 955c6d244fa5e9615536e23355f4997468d86c72..f5ac2e4af7bd6069da83c3343e1d541e44718c8e 100644 (file)
                                 // Include mouse wheel support
 
 // Compile wxUIActionSimulator class?
-//
-// This is experimental code subject to change. It's not fully implemented yet.
-#define wxUSE_UIACTIONSIMULATOR 0
+#define wxUSE_UIACTIONSIMULATOR 1
 
 // ----------------------------------------------------------------------------
 // wxDC classes for various output formats
index 58314a3af3a6c4f2a27f6bc0abc65621c9439691..4a2210c91f604a7d949c7f500e0e8c9142332e85 100644 (file)
                                 // Include mouse wheel support
 
 // Compile wxUIActionSimulator class?
-//
-// This is experimental code subject to change. It's not fully implemented yet.
-#define wxUSE_UIACTIONSIMULATOR 0
+#define wxUSE_UIACTIONSIMULATOR 1
 
 // ----------------------------------------------------------------------------
 // wxDC classes for various output formats
index 0cb30ad968f80ad81f73bfea20b7b5ffead4fe61..b8f731c9c9cb40c0bf06ccf2972330c63edfd3de 100644 (file)
                                 // Include mouse wheel support
 
 // Compile wxUIActionSimulator class?
-//
-// This is experimental code subject to change. It's not fully implemented yet.
-#define wxUSE_UIACTIONSIMULATOR 0
+#define wxUSE_UIACTIONSIMULATOR 1
 
 // ----------------------------------------------------------------------------
 // wxDC classes for various output formats
index 9b6bbe57a91ef36e399bfa56eb7b3f4dd042c62f..45ba6ad2af8428128e0a7adf086a020033c6074c 100644 (file)
                                 // Include mouse wheel support
 
 // Compile wxUIActionSimulator class?
-//
-// This is experimental code subject to change. It's not fully implemented yet.
-#define wxUSE_UIACTIONSIMULATOR 0
+#define wxUSE_UIACTIONSIMULATOR 1
 
 // ----------------------------------------------------------------------------
 // wxDC classes for various output formats
index 1093b269540b395610dc5e884e6268be15e55299..29ef9e4b433fb65346a261b0e4869263a1edf8cf 100644 (file)
                                 // Include mouse wheel support
 
 // Compile wxUIActionSimulator class?
-//
-// This is experimental code subject to change. It's not fully implemented yet.
-#define wxUSE_UIACTIONSIMULATOR 0
+#define wxUSE_UIACTIONSIMULATOR 1
 
 // ----------------------------------------------------------------------------
 // wxDC classes for various output formats
index 3ddfa59f786913e8d6cf2ad898be6c1b01ce606d..7c806a13766c9f80d7511befccb29bb7152318af 100644 (file)
                                 // Include mouse wheel support
 
 // Compile wxUIActionSimulator class?
-//
-// This is experimental code subject to change. It's not fully implemented yet.
-#define wxUSE_UIACTIONSIMULATOR 0
+#define wxUSE_UIACTIONSIMULATOR 1
 
 // ----------------------------------------------------------------------------
 // wxDC classes for various output formats
index 9f6cb8cac0101cd4fc9538b4c9df8ba7daa221de..0db49ad1bd0017b22ee5504410a793e186d63a9b 100644 (file)
                                 // Include mouse wheel support
 
 // Compile wxUIActionSimulator class?
-//
-// This is experimental code subject to change. It's not fully implemented yet.
-#define wxUSE_UIACTIONSIMULATOR 0
+#define wxUSE_UIACTIONSIMULATOR 1
 
 // ----------------------------------------------------------------------------
 // wxDC classes for various output formats
index a08aea76aa2e0bdda4f7a442f40baee5ce29a43d..e662b2c3c32e780464a6c29dffdc29cebe300c3c 100644 (file)
@@ -1,11 +1,13 @@
 /////////////////////////////////////////////////////////////////////////////
 // Name:        wx/uiaction.h
 // Purpose:     wxUIActionSimulator interface
-// Author:      Kevin Ollivier
+// Author:      Kevin Ollivier, Steven Lamerton, Vadim Zeitlin
 // Modified by:
 // Created:     2010-03-06
 // RCS-ID:      $Id: menu.cpp 54129 2008-06-11 19:30:52Z SC $
 // Copyright:   (c) Kevin Ollivier
+//              (c) 2010 Steven Lamerton
+//              (c) 2010 Vadim Zeitlin
 // Licence:     wxWindows licence
 /////////////////////////////////////////////////////////////////////////////
 
 
 #if wxUSE_UIACTIONSIMULATOR
 
-#include "wx/event.h"
-#include "wx/dynarray.h"
+#include "wx/mousestate.h"  // for wxMOUSE_BTN_XXX constants
 
 class WXDLLIMPEXP_CORE wxUIActionSimulator
 {
 public:
-    wxUIActionSimulator();
-    ~wxUIActionSimulator();
+    wxUIActionSimulator() { }
 
-    // Mouse related
-    bool        MouseMove(long x, long y);
-    bool        MouseDown(int button = wxMOUSE_BTN_LEFT);
-    bool        MouseUp(int button = wxMOUSE_BTN_LEFT);
-    bool        MouseClick(int button = wxMOUSE_BTN_LEFT);
-    bool        MouseDblClick(int button = wxMOUSE_BTN_LEFT);
-    bool        MouseDragDrop(long x1, long y1, long x2, long y2, int button = wxMOUSE_BTN_LEFT);
 
-    // Keyboard related:
+    // Default dtor, copy ctor and assignment operator are ok (even though the
+    // last two don't make much sense for this class).
 
-    bool        KeyDown(int keycode, bool shiftDown=false, bool cmdDown=false, bool altDown=false)
-                    { return Key(keycode, true, shiftDown, cmdDown, altDown); }
 
-    bool        KeyUp(int keycode, bool shiftDown=false, bool cmdDown=false, bool altDown=false)
-                    { return Key(keycode, false, shiftDown, cmdDown, altDown); }
+    // Mouse simulation
+    // ----------------
 
-    bool        Char(int keycode, bool shiftDown=false, bool cmdDown=false, bool altDown=false);
+    // Low level methods
+    bool MouseMove(long x, long y);
+    bool MouseMove(const wxPoint& point) { return MouseMove(point.x, point.y); }
 
-protected:
-    // Implementation-wise, since key events take more code to set up on GTK and Mac, it makes
-    // sense to handle both key down and key up in one method. However, I wanted the API for pressing
-    // and releasing the mouse and keyboard to be consistent, and I don't really like using a bool
-    // for pressed state, so I'm leaving this as an implementation detail.
-    bool        Key(int keycode, bool isDown=true, bool shiftDown=false, bool cmdDown=false, bool altDown=false);
+    bool MouseDown(int button = wxMOUSE_BTN_LEFT);
+    bool MouseUp(int button = wxMOUSE_BTN_LEFT);
+
+    // Higher level interface, use it if possible instead
+    bool MouseClick(int button = wxMOUSE_BTN_LEFT);
+    bool MouseDblClick(int button = wxMOUSE_BTN_LEFT);
+    bool MouseDragDrop(long x1, long y1, long x2, long y2,
+                       int button = wxMOUSE_BTN_LEFT);
+
+
+    // Keyboard simulation
+    // -------------------
+
+    // Low level methods for generating key presses and releases
+    bool KeyDown(int keycode, int modifiers = wxMOD_NONE)
+        { return Key(keycode, modifiers, true); }
+
+    bool KeyUp(int keycode, int modifiers = wxMOD_NONE)
+        { return Key(keycode, modifiers, false); }
+
+    // Higher level methods for generating both the key press and release for a
+    // single key or for all characters in the ASCII string "text" which can
+    // currently contain letters only (no digits, no punctuation).
+    bool Char(int keycode, int modifiers = wxMOD_NONE);
+
+    bool Text(const char *text);
+
+private:
+    // This is the common part of Key{Down,Up}() methods: while we keep them
+    // separate at public API level for consistency with Mouse{Down,Up}(), at
+    // implementation level it makes more sense to have them in a single
+    // function.
+    //
+    // This is a simple wrapper verifying the input parameters validity around
+    // the platform-specific DoKey() method implemented in platform-specific
+    // files.
+    bool Key(int keycode, int modifiers, bool isDown);
+
+    bool DoKey(int keycode, int modifiers, bool isDown);
 };
 
 #endif // wxUSE_UIACTIONSIMULATOR
index afea2b1a6d3e0db8de224e1f8c25522af6391fdc..a6fc8f7855e060f0f8d7b08b2e377dd135d54db0 100644 (file)
                                 // Include mouse wheel support
 
 // Compile wxUIActionSimulator class?
-//
-// This is experimental code subject to change. It's not fully implemented yet.
-#define wxUSE_UIACTIONSIMULATOR 0
+#define wxUSE_UIACTIONSIMULATOR 1
 
 // ----------------------------------------------------------------------------
 // wxDC classes for various output formats
index 4fbca1af5c8c95e115c82bc4e6ba1894c99db690..11bb7b7b9e0440c7ce6271f75215d055e6763990 100644 (file)
 #if defined(__WXGTK__)
 typedef void WXDisplay;
 typedef void* WXWindow;
+typedef unsigned long WXKeySym;
 #endif
 
+int wxCharCodeXToWX(WXKeySym keySym);
+WXKeySym wxCharCodeWXToX(int id);
+
 class wxIconBundle;
 
 void wxSetIconsX11( WXDisplay* display, WXWindow window,
index 4767a9431d39ed2644ecad63f522b77c0f788b4b..ef445f3ba3e75426fcb716b67fc2a269932cfcfe 100644 (file)
@@ -35,9 +35,6 @@ class WXDLLIMPEXP_FWD_CORE wxRegion;
 // key events related functions
 // ----------------------------------------------------------------------------
 
-extern int wxCharCodeXToWX(KeySym keySym);
-extern KeySym wxCharCodeWXToX(int id);
-
 WXPixel wxGetBestMatchingPixel(Display *display, XColor *desiredColor, Colormap cmap);
 Pixmap XCreateInsensitivePixmap( Display *display, Pixmap pixmap );
 
index c8a922ca902c3766e7b48ce81e9d8f4caa1521d2..b74ef64de0bedc2963cbba96656e43c304b4d4d0 100644 (file)
     wxUIActionSimulator is a class used to simulate user interface actions
     such as a mouse click or a key press.
 
-    @note that this class is currently experimental and disabled by default,
-    you must set @c wxUSE_UIACTIONSIMULATOR to 1 in your setup.h file or use
-    configure @c --enable-uiactionsim option to enable it.
+    Common usage for this class would be to provide playback and record (aka
+    macro recording) functionality for users, or to drive unit tests by
+    simulating user sessions.
 
-    Common usages for this class would be to provide playback and record (aka macro recording)
-    functionality for users, or to drive unit tests by simulating user sessions.
+    See the @ref page_samples_uiaction for an example of using this class.
 
-    See the uiaction sample for example usage of this class.
-
-    NOTE: For keyboard operations, currently you must pass the keycode of the actual
-    key on the keyboard. To simulate, e.g. IME actions, you'd need to simulate the actual
-    keypresses needed to active the IME, then the keypresses needed to type and select
-    the desired character.
+    @since 2.9.2
 
     @library{wxcore}
 */
 
 class wxUIActionSimulator
 {
-  public:
+public:
     /**
-        Constructor.
+        Default constructor.
     */
     wxUIActionSimulator();
-    ~wxUIActionSimulator();
 
     /**
         Move the mouse to the specified coordinates.
@@ -47,37 +40,49 @@ class wxUIActionSimulator
         @param y
             y coordinate to move to, in screen coordinates.
     */
-    bool        MouseMove(long x, long y);
+    bool MouseMove(long x, long y);
+
+    /**
+        Move the mouse to the specified coordinates.
+
+        @param point
+            Point to move to, in screen coordinates.
+    */
+    bool MouseMove(const wxPoint& point);
 
     /**
         Press a mouse button.
 
         @param button
-            Button to press. Valid constants are wxMOUSE_BTN_LEFT, wxMOUSE_BTN_MIDDLE, and wxMOUSE_BTN_RIGHT.
+            Button to press. Valid constants are @c wxMOUSE_BTN_LEFT,
+            @c wxMOUSE_BTN_MIDDLE, and @c wxMOUSE_BTN_RIGHT.
     */
-    bool        MouseDown(int button = wxMOUSE_BTN_LEFT);
+    bool MouseDown(int button = wxMOUSE_BTN_LEFT);
 
     /**
         Release a mouse button.
 
         @param button
-            Button to press. See wxUIActionSimulator::MouseDown for a list of valid constants.
+            Button to press. See wxUIActionSimulator::MouseDown for a list of
+            valid constants.
     */
-    bool        MouseUp(int button = wxMOUSE_BTN_LEFT);
+    bool MouseUp(int button = wxMOUSE_BTN_LEFT);
     /**
         Click a mouse button.
 
         @param button
-            Button to press. See wxUIActionSimulator::MouseDown for a list of valid constants.
+            Button to press. See wxUIActionSimulator::MouseDown for a list of
+            valid constants.
     */
-    bool        MouseClick(int button = wxMOUSE_BTN_LEFT);
+    bool MouseClick(int button = wxMOUSE_BTN_LEFT);
     /**
         Double-click a mouse button.
 
         @param button
-            Button to press. See wxUIActionSimulator::MouseDown for a list of valid constants.
+            Button to press. See wxUIActionSimulator::MouseDown for a list of
+            valid constants.
     */
-    bool        MouseDblClick(int button = wxMOUSE_BTN_LEFT);
+    bool MouseDblClick(int button = wxMOUSE_BTN_LEFT);
 
     /**
         Perform a drag and drop operation.
@@ -95,59 +100,60 @@ class wxUIActionSimulator
             y destination coordinate, in screen coordinates.
 
         @param button
-            Button to press. See wxUIActionSimulator::MouseDown for a list of valid constants.
+            Button to press. See wxUIActionSimulator::MouseDown for a list of
+            valid constants.
     */
-    bool        MouseDragDrop(long x1, long y1, long x2, long y2, int button = wxMOUSE_BTN_LEFT);
+    bool MouseDragDrop(long x1, long y1, long x2, long y2,
+                       int button = wxMOUSE_BTN_LEFT);
 
     /**
         Press a key.
 
-        @param keycode
-            key to operate on, as an integer.
-
-        @param shiftDown
-            true if the shift key should be pressed, false otherwise.
+        If you are using modifiers then it needs to be paired with an identical
+        KeyUp or the modifiers will not be released (MSW and OSX).
 
-        @param cmdDown
-            true if the cmd key should be pressed, false otherwise.
+        @param keycode
+            Key to operate on, as an integer. It is interpreted as a wxKeyCode.
 
-        @param altDown
-            true if the alt key should be pressed, false otherwise.
+        @param modifiers
+            A combination of ::wxKeyModifier flags to be pressed with the given
+            keycode.
     */
-    bool        KeyDown(int keycode, bool shiftDown=false, bool cmdDown=false, bool altDown=false);
+    bool KeyDown(int keycode, int modifiers = wxMOD_NONE);
 
     /**
         Release a key.
 
         @param keycode
-            key to operate on, as an integer.
-
-        @param shiftDown
-            true if the shift key should be pressed, false otherwise.
-
-        @param cmdDown
-            true if the cmd key should be pressed, false otherwise.
+            Key to operate on, as an integer. It is interpreted as a wxKeyCode.
 
-        @param altDown
-            true if the alt key should be pressed, false otherwise.
+        @param modifiers
+            A combination of ::wxKeyModifier flags to be pressed with the given
+            keycode.
     */
-    bool        KeyUp(int keycode, bool shiftDown=false, bool cmdDown=false, bool altDown=false);
+    bool KeyUp(int keycode, int modifiers = wxMOD_NONE);
 
     /**
         Press and release a key.
 
         @param keycode
-            key to operate on, as an integer.
+            Key to operate on, as an integer. It is interpreted as a wxKeyCode.
 
-        @param shiftDown
-            true if the shift key should be pressed, false otherwise.
+        @param modifiers
+            A combination of ::wxKeyModifier flags to be pressed with the given
+            keycode.
+    */
+    bool Char(int keycode, int modifiers = wxMOD_NONE);
+
+    /**
+        Emulate typing in the keys representing the given string.
 
-        @param cmdDown
-            true if the cmd key should be pressed, false otherwise.
+        Currently only the ASCII letters (i.e. characters @c a-z and @c A-Z)
+        are supported.
 
-        @param altDown
-            true if the alt key should be pressed, false otherwise.
+        @param text
+            The string to type.
     */
-    bool        Char(int keycode, bool shiftDown=false, bool cmdDown=false, bool altDown=false);
+    bool Text(const wxString& text);
 };
 
index 63a5bb627103575244367c19dc7fb60942dbf4ac..3b6d0785872a498c4a98d0ddd49820dbea8e0368 100644 (file)
@@ -5,7 +5,7 @@
 // Modified by:
 // Created:     04/01/98
 // RCS-ID:      $Id$
-// Copyright:   (c) Kevin Ollivier
+// Copyright:   (c) Kevin Ollivier, Steven Lamerton
 // Licence:     wxWindows licence
 /////////////////////////////////////////////////////////////////////////////
 
 // ----------------------------------------------------------------------------
 // headers
 // ----------------------------------------------------------------------------
+
 // For compilers that support precompilation, includes "wx/wx.h".
 #include "wx/wxprec.h"
+
 #ifdef __BORLANDC__
     #pragma hdrstop
 #endif
@@ -52,8 +52,7 @@
 enum
 {
     // menu items
-    TheButton = 100,
-    RunSimulation
+    RunSimulation = 1
 };
 
 // ----------------------------------------------------------------------------
@@ -76,22 +75,21 @@ public:
     // ctor(s)
     MyFrame(const wxString& title);
 
-    void OnButtonPressed(wxCommandEvent&);
-    void OnRunSimulation(wxCommandEvent&);
-    
-    bool ButtonPressed() const { return m_buttonPressed; }
-    bool MenuSelected() const { return m_menuSelected; }
-    
+    void OnButtonPressed(wxCommandEvent& event);
+    void OnRunSimulation(wxCommandEvent& event);
+    void OnExit(wxCommandEvent& WXUNUSED(event)) { Close(); }
+
 private:
-    bool m_buttonPressed;
-    bool m_menuSelected;
+    wxButton* m_button;
+    wxTextCtrl* m_text;
 
     DECLARE_EVENT_TABLE()
 };
 
 BEGIN_EVENT_TABLE(MyFrame, wxFrame)
-    EVT_BUTTON(TheButton, MyFrame::OnButtonPressed)
+    EVT_BUTTON(wxID_ANY, MyFrame::OnButtonPressed)
     EVT_MENU(RunSimulation, MyFrame::OnRunSimulation)
+    EVT_MENU(wxID_EXIT, MyFrame::OnExit)
 END_EVENT_TABLE()
 
 #endif // wxUSE_UIACTIONSIMULATOR
@@ -114,7 +112,7 @@ bool MyApp::OnInit()
 #if wxUSE_UIACTIONSIMULATOR
     MyFrame *frame = new MyFrame("wxUIActionSimulator sample application");
     frame->Show(true);
-    
+
     return true;
 #else // !wxUSE_UIACTIONSIMULATOR
     wxLogError("wxUSE_UIACTIONSIMULATOR must be 1 for this sample");
@@ -134,9 +132,6 @@ MyFrame::MyFrame(const wxString& title)
 {
     SetIcon(wxICON(sample));
 
-    m_buttonPressed = false;
-    m_menuSelected = false;
-
 #if wxUSE_MENUS
     // create a menu bar
     wxMenu *fileMenu = new wxMenu;
@@ -152,30 +147,48 @@ MyFrame::MyFrame(const wxString& title)
     SetMenuBar(menuBar);
 #endif // wxUSE_MENUS
 
-    wxButton* button = new wxButton(this, TheButton, "Button");
-    button->SetName("TheButton");
+    wxPanel *panel = new wxPanel(this);
+
+    wxBoxSizer* sizer = new wxBoxSizer(wxVERTICAL);
+    panel->SetSizer(sizer);
+
+    m_button = new wxButton(panel, wxID_ANY, "&Button");
+    sizer->Add(m_button, wxSizerFlags().Centre().Border());
+
+    m_text = new wxTextCtrl(panel, wxID_ANY, "",
+                            wxDefaultPosition, wxDefaultSize,
+                            wxTE_MULTILINE);
+    sizer->Add(m_text, wxSizerFlags(1).Expand().Border());
 }
 
 
 // event handlers
 
-void MyFrame::OnRunSimulation(wxCommandEvent&)
+void MyFrame::OnRunSimulation(wxCommandEvent& WXUNUSED(event))
 {
     wxUIActionSimulator sim;
-    wxWindow* button = FindWindow(wxString("TheButton"));
-    wxPoint globalPoint = button->ClientToScreen(wxPoint(20, 10));
-    sim.MouseMove(globalPoint.x, globalPoint.y);
+
+    // Add some extra distance to take account of window decorations
+    sim.MouseMove(m_button->GetScreenPosition() + wxPoint(10, 10));
     sim.MouseClick(wxMOUSE_BTN_LEFT);
-    
+
+    // Process the resulting button event
     wxYield();
-    
-    if (ButtonPressed())
-        wxMessageBox("Button automagically pressed!");
+
+    m_text->SetFocus();
+    sim.Char('A');
+    sim.Char('A', wxMOD_SHIFT);
+    sim.Char(WXK_RETURN);
+    sim.Char('Z');
+    sim.Char('Z', wxMOD_SHIFT);
+    sim.Char(WXK_RETURN);
+    sim.Text("aAbBcC");
+    sim.Char(WXK_RETURN);
 }
 
-void MyFrame::OnButtonPressed(wxCommandEvent&)
+void MyFrame::OnButtonPressed(wxCommandEvent& WXUNUSED(event))
 {
-    m_buttonPressed = true;
+    m_text->AppendText("Button pressed.\n");
 }
 
 #endif // wxUSE_UIACTIONSIMULATOR
index 20c4141cab6787e00e926e48d7f6867364fb2f3b..fce28719e39f047594047c66727298159da162e8 100644 (file)
@@ -1,11 +1,13 @@
 /////////////////////////////////////////////////////////////////////////////
 // Name:        src/common/uiactioncmn.cpp
 // Purpose:     wxUIActionSimulator common implementation
-// Author:      Kevin Ollivier
+// Author:      Kevin Ollivier, Steven Lamerton, Vadim Zeitlin
 // Modified by:
 // Created:     2010-03-06
 // RCS-ID:      $Id: menu.cpp 54129 2008-06-11 19:30:52Z SC $
 // Copyright:   (c) Kevin Ollivier
+//              (c) 2010 Steven Lamerton
+//              (c) 2010 Vadim Zeitlin
 // Licence:     wxWindows licence
 /////////////////////////////////////////////////////////////////////////////
 
 
 #include "wx/uiaction.h"
 
-wxUIActionSimulator::wxUIActionSimulator()
-{
-}
-
-wxUIActionSimulator::~wxUIActionSimulator()
-{
-}
-
-
 bool wxUIActionSimulator::MouseClick(int button)
 {
     MouseDown(button);
@@ -42,7 +35,9 @@ bool wxUIActionSimulator::MouseDblClick(int button)
     return true;
 }
 
-bool wxUIActionSimulator::MouseDragDrop(long x1, long y1, long x2, long y2, int button)
+bool
+wxUIActionSimulator::MouseDragDrop(long x1, long y1, long x2, long y2,
+                                   int button)
 {
     MouseMove(x1, y1);
     MouseDown(button);
@@ -52,10 +47,40 @@ bool wxUIActionSimulator::MouseDragDrop(long x1, long y1, long x2, long y2, int
     return true;
 }
 
-bool  wxUIActionSimulator::Char(int keycode, bool shiftDown, bool cmdDown, bool altDown)
+bool
+wxUIActionSimulator::Key(int keycode, int modifiers, bool isDown)
+{
+    wxASSERT_MSG( !(modifiers & wxMOD_CONTROL),
+        "wxMOD_CONTROL is not implemented, use wxMOD_CMD instead" );
+    wxASSERT_MSG( (modifiers & wxMOD_ALTGR) != wxMOD_ALTGR,
+        "wxMOD_ALTGR is not implemented" );
+    wxASSERT_MSG( !(modifiers & wxMOD_META ),
+        "wxMOD_META is not implemented" );
+    wxASSERT_MSG( !(modifiers & wxMOD_WIN ),
+        "wxMOD_WIN is not implemented" );
+
+    return DoKey(keycode, modifiers, isDown);
+}
+
+bool  wxUIActionSimulator::Char(int keycode, int modifiers)
+{
+    Key(keycode, modifiers, true);
+    Key(keycode, modifiers, false);
+
+    return true;
+}
+
+bool wxUIActionSimulator::Text(const char *s)
 {
-    Key(keycode, false, shiftDown, cmdDown, altDown);
-    Key(keycode, true, shiftDown, cmdDown, altDown);
+    while ( *s != '\0' )
+    {
+        const char ch = *s++;
+
+        wxASSERT_MSG( ch, "Only letters are allowed" );
+
+        if ( !Char(ch, isupper(ch) ? wxMOD_SHIFT : 0) )
+            return false;
+    }
 
     return true;
 }
index d421b9a18f993515499029e3dd6f9f6e75c562e3..e9128a633575e7399b4d17a7d25c1690c0044a36 100644 (file)
@@ -1,11 +1,13 @@
 /////////////////////////////////////////////////////////////////////////////
 // Name:        src/msw/uiaction.cpp
 // Purpose:     wxUIActionSimulator implementation
-// Author:      Kevin Ollivier
+// Author:      Kevin Ollivier, Steven Lamerton, Vadim Zeitlin
 // Modified by:
 // Created:     2010-03-06
 // RCS-ID:      $Id: menu.cpp 54129 2008-06-11 19:30:52Z SC $
 // Copyright:   (c) Kevin Ollivier
+//              (c) 2010 Steven Lamerton
+//              (c) 2010 Vadim Zeitlin
 // Licence:     wxWindows licence
 /////////////////////////////////////////////////////////////////////////////
 
 
 #include "wx/msw/wrapwin.h"
 
+namespace
+{
+
 DWORD EventTypeForMouseButton(int button, bool isDown)
 {
     switch (button)
     {
         case wxMOUSE_BTN_LEFT:
-            if (isDown)
-                return MOUSEEVENTF_LEFTDOWN;
-            else
-                return MOUSEEVENTF_LEFTUP;
+            return isDown ? MOUSEEVENTF_LEFTDOWN : MOUSEEVENTF_LEFTUP;
+
         case wxMOUSE_BTN_RIGHT:
-            if (isDown)
-                return MOUSEEVENTF_RIGHTDOWN;
-            else
-                return MOUSEEVENTF_RIGHTUP;
+            return isDown ? MOUSEEVENTF_RIGHTDOWN : MOUSEEVENTF_RIGHTUP;
+
         case wxMOUSE_BTN_MIDDLE:
-            if (isDown)
-                return MOUSEEVENTF_MIDDLEDOWN;
-            else
-                return MOUSEEVENTF_MIDDLEUP;
+            return isDown ? MOUSEEVENTF_MIDDLEDOWN : MOUSEEVENTF_MIDDLEUP;
 
         default:
             wxFAIL_MSG("Unsupported button passed in.");
-            return -1;
+            return (DWORD)-1;
     }
 }
 
+void DoSimulateKbdEvent(DWORD vk, bool isDown)
+{
+    keybd_event(vk, 0, isDown ? 0 : KEYEVENTF_KEYUP, 0);
+}
+
+} // anonymous namespace
+
 bool wxUIActionSimulator::MouseDown(int button)
 {
     POINT p;
@@ -53,7 +58,13 @@ bool wxUIActionSimulator::MouseDown(int button)
 
 bool wxUIActionSimulator::MouseMove(long x, long y)
 {
-    mouse_event(MOUSEEVENTF_MOVE, x, y, 0, 0);
+    // Because MOUSEEVENTF_ABSOLUTE takes measurements scaled between 0 & 65535
+    // we need to scale our input too
+    int displayx, displayy, scaledx, scaledy;
+    wxDisplaySize(&displayx, &displayy);
+    scaledx = ((float)x / displayx) * 65535;
+    scaledy = ((float)y / displayy) * 65535;
+    mouse_event(MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE, scaledx, scaledy, 0, 0);
     return true;
 }
 
@@ -65,12 +76,31 @@ bool wxUIActionSimulator::MouseUp(int button)
     return true;
 }
 
-bool wxUIActionSimulator::Key(int keycode, bool isDown, bool shiftDown, bool cmdDown, bool altDown)
+bool wxUIActionSimulator::DoKey(int keycode, int modifiers, bool isDown)
 {
-    DWORD flags = 0;
+    if (isDown)
+    {
+        if (modifiers & wxMOD_SHIFT)
+            DoSimulateKbdEvent(VK_SHIFT, true);
+        if (modifiers & wxMOD_ALT)
+            DoSimulateKbdEvent(VK_MENU, true);
+        if (modifiers & wxMOD_CMD)
+            DoSimulateKbdEvent(VK_CONTROL, true);
+    }
+
+    DWORD vkkeycode = wxCharCodeWXToMSW(keycode);
+    keybd_event(vkkeycode, 0, isDown ? 0 : KEYEVENTF_KEYUP, 0);
+
     if (!isDown)
-        flags = KEYEVENTF_KEYUP;
-    keybd_event(keycode, 0, flags, 0);
+    {
+        if (modifiers & wxMOD_SHIFT)
+            DoSimulateKbdEvent(VK_SHIFT, false);
+        if (modifiers & wxMOD_ALT)
+            DoSimulateKbdEvent(VK_MENU, false);
+        if (modifiers & wxMOD_CMD)
+            DoSimulateKbdEvent(VK_CONTROL, false);
+    }
+
     return true;
 }
 
index 603b3039774b9678b0708c76dbc42d206f1c777a..a1667c6bfb31965f29012ae5e2707596847e3303 100644 (file)
@@ -1,11 +1,13 @@
 /////////////////////////////////////////////////////////////////////////////
 // Name:        src/osx/uiaction_osx.cpp
 // Purpose:     wxUIActionSimulator implementation
-// Author:      Kevin Ollivier
+// Author:      Kevin Ollivier, Steven Lamerton, Vadim Zeitlin
 // Modified by:
 // Created:     2010-03-06
 // RCS-ID:      $Id: menu.cpp 54129 2008-06-11 19:30:52Z SC $
 // Copyright:   (c) Kevin Ollivier
+//              (c) 2010 Steven Lamerton
+//              (c) 2010 Vadim Zeitlin
 // Licence:     wxWindows licence
 /////////////////////////////////////////////////////////////////////////////
 
 
 #include "wx/uiaction.h"
 
-#include <ApplicationServices/ApplicationServices.h>
+#include "wx/log.h"
+
+#include "wx/osx/private.h"
+#include "wx/osx/core/cfref.h"
+
+namespace
+{
 
 CGEventTapLocation tap = kCGSessionEventTap;
 
 CGEventType CGEventTypeForMouseButton(int button, bool isDown)
 {
-    switch (button)
+    switch ( button )
     {
         case wxMOUSE_BTN_LEFT:
-            if (isDown)
-                return kCGEventLeftMouseDown;
-            else
-                return kCGEventLeftMouseUp;
-        case wxMOUSE_BTN_RIGHT:
-            if (isDown)
-                return kCGEventRightMouseDown;
-            else
-                return kCGEventRightMouseUp;
+            return isDown ? kCGEventLeftMouseDown : kCGEventLeftMouseUp;
 
-        // Apparently all other buttons use the constant OtherMouseDown
+        case wxMOUSE_BTN_RIGHT:
+            return isDown ? kCGEventRightMouseDown : kCGEventRightMouseUp;
 
+        // All the other buttons use the constant OtherMouseDown but we still
+        // want to check for invalid parameters so assert first
         default:
-            if (isDown)
-                return kCGEventOtherMouseDown;
-            else
-                return kCGEventOtherMouseUp;
+            wxFAIL_MSG("Unsupported button passed in.");
+            // fall back to the only known remaining case
+
+        case wxMOUSE_BTN_MIDDLE:
+            return isDown ? kCGEventOtherMouseDown : kCGEventOtherMouseUp;
     }
 }
 
-void SendCharCode(CGCharCode keycode, bool isDown)
+CGPoint GetMousePosition()
 {
-    CGEventRef event = CGEventCreateKeyboardEvent(NULL, keycode, isDown);
-    if (event)
+    int x, y;
+    wxGetMousePosition(&x, &y);
+
+    CGPoint pos;
+    pos.x = x;
+    pos.y = y;
+
+    return pos;
+}
+
+bool SendCharCode(CGKeyCode keycode, bool isDown)
+{
+    wxCFRef<CGEventRef>
+        event(CGEventCreateKeyboardEvent(NULL, keycode, isDown));
+    if ( !event )
+        return false;
+
+    CGEventPost(kCGHIDEventTap, event);
+    return true;
+}
+
+CGKeyCode wxCharCodeWXToOSX(wxKeyCode code)
+{
+    CGKeyCode keycode;
+
+    switch (code)
     {
-        CGEventPost(kCGHIDEventTap, event);
+        case 'a': case 'A':   keycode = kVK_ANSI_A; break;
+        case 'b': case 'B':   keycode = kVK_ANSI_B; break;
+        case 'c': case 'C':   keycode = kVK_ANSI_C; break;
+        case 'd': case 'D':   keycode = kVK_ANSI_D; break;
+        case 'e': case 'E':   keycode = kVK_ANSI_E; break;
+        case 'f': case 'F':   keycode = kVK_ANSI_F; break;
+        case 'g': case 'G':   keycode = kVK_ANSI_G; break;
+        case 'h': case 'H':   keycode = kVK_ANSI_H; break;
+        case 'i': case 'I':   keycode = kVK_ANSI_I; break;
+        case 'j': case 'J':   keycode = kVK_ANSI_J; break;
+        case 'k': case 'K':   keycode = kVK_ANSI_K; break;
+        case 'l': case 'L':   keycode = kVK_ANSI_L; break;
+        case 'm': case 'M':   keycode = kVK_ANSI_M; break;
+        case 'n': case 'N':   keycode = kVK_ANSI_N; break;
+        case 'o': case 'O':   keycode = kVK_ANSI_O; break;
+        case 'p': case 'P':   keycode = kVK_ANSI_P; break;
+        case 'q': case 'Q':   keycode = kVK_ANSI_Q; break;
+        case 'r': case 'R':   keycode = kVK_ANSI_R; break;
+        case 's': case 'S':   keycode = kVK_ANSI_S; break;
+        case 't': case 'T':   keycode = kVK_ANSI_T; break;
+        case 'u': case 'U':   keycode = kVK_ANSI_U; break;
+        case 'v': case 'V':   keycode = kVK_ANSI_V; break;
+        case 'w': case 'W':   keycode = kVK_ANSI_W; break;
+        case 'x': case 'X':   keycode = kVK_ANSI_X; break;
+        case 'y': case 'Y':   keycode = kVK_ANSI_Y; break;
+        case 'z': case 'Z':   keycode = kVK_ANSI_Z; break;
+
+        case '0':             keycode = kVK_ANSI_0; break;
+        case '1':             keycode = kVK_ANSI_1; break;
+        case '2':             keycode = kVK_ANSI_2; break;
+        case '3':             keycode = kVK_ANSI_3; break;
+        case '4':             keycode = kVK_ANSI_4; break;
+        case '5':             keycode = kVK_ANSI_5; break;
+        case '6':             keycode = kVK_ANSI_6; break;
+        case '7':             keycode = kVK_ANSI_7; break;
+        case '8':             keycode = kVK_ANSI_8; break;
+        case '9':             keycode = kVK_ANSI_9; break;
+
+        case WXK_BACK:        keycode = kVK_Delete; break;
+        case WXK_TAB:         keycode = kVK_Tab; break;
+        case WXK_RETURN:      keycode = kVK_Return; break;
+        case WXK_ESCAPE:      keycode = kVK_Escape; break;
+        case WXK_SPACE:       keycode = kVK_Space; break;
+        case WXK_DELETE:      keycode = kVK_Delete; break;
+
+        case WXK_SHIFT:       keycode = kVK_Shift; break;
+        case WXK_ALT:         keycode = kVK_Option; break;
+        case WXK_CONTROL:     keycode = kVK_Control; break;
+        case WXK_COMMAND:     keycode = kVK_Command; break;
+
+        case WXK_CAPITAL:     keycode = kVK_CapsLock; break;
+        case WXK_END:         keycode = kVK_End; break;
+        case WXK_HOME:        keycode = kVK_Home; break;
+        case WXK_LEFT:        keycode = kVK_LeftArrow; break;
+        case WXK_UP:          keycode = kVK_UpArrow; break;
+        case WXK_RIGHT:       keycode = kVK_RightArrow; break;
+        case WXK_DOWN:        keycode = kVK_DownArrow; break;
+
+        case WXK_HELP:        keycode = kVK_Help; break;
+
+
+        case WXK_NUMPAD0:     keycode = kVK_ANSI_Keypad0; break;
+        case WXK_NUMPAD1:     keycode = kVK_ANSI_Keypad1; break;
+        case WXK_NUMPAD2:     keycode = kVK_ANSI_Keypad2; break;
+        case WXK_NUMPAD3:     keycode = kVK_ANSI_Keypad3; break;
+        case WXK_NUMPAD4:     keycode = kVK_ANSI_Keypad4; break;
+        case WXK_NUMPAD5:     keycode = kVK_ANSI_Keypad5; break;
+        case WXK_NUMPAD6:     keycode = kVK_ANSI_Keypad6; break;
+        case WXK_NUMPAD7:     keycode = kVK_ANSI_Keypad7; break;
+        case WXK_NUMPAD8:     keycode = kVK_ANSI_Keypad8; break;
+        case WXK_NUMPAD9:     keycode = kVK_ANSI_Keypad9; break;
+        case WXK_F1:          keycode = kVK_F1; break;
+        case WXK_F2:          keycode = kVK_F2; break;
+        case WXK_F3:          keycode = kVK_F3; break;
+        case WXK_F4:          keycode = kVK_F4; break;
+        case WXK_F5:          keycode = kVK_F5; break;
+        case WXK_F6:          keycode = kVK_F6; break;
+        case WXK_F7:          keycode = kVK_F7; break;
+        case WXK_F8:          keycode = kVK_F8; break;
+        case WXK_F9:          keycode = kVK_F9; break;
+        case WXK_F10:         keycode = kVK_F10; break;
+        case WXK_F11:         keycode = kVK_F11; break;
+        case WXK_F12:         keycode = kVK_F12; break;
+        case WXK_F13:         keycode = kVK_F13; break;
+        case WXK_F14:         keycode = kVK_F14; break;
+        case WXK_F15:         keycode = kVK_F15; break;
+        case WXK_F16:         keycode = kVK_F16; break;
+        case WXK_F17:         keycode = kVK_F17; break;
+        case WXK_F18:         keycode = kVK_F18; break;
+        case WXK_F19:         keycode = kVK_F19; break;
+        case WXK_F20:         keycode = kVK_F20; break;
+
+        case WXK_PAGEUP:      keycode = kVK_PageUp; break;
+        case WXK_PAGEDOWN:    keycode = kVK_PageDown; break;
+
+        case WXK_NUMPAD_DELETE:    keycode = kVK_ANSI_KeypadClear; break;
+        case WXK_NUMPAD_EQUAL:     keycode = kVK_ANSI_KeypadEquals; break;
+        case WXK_NUMPAD_MULTIPLY:  keycode = kVK_ANSI_KeypadMultiply; break;
+        case WXK_NUMPAD_ADD:       keycode = kVK_ANSI_KeypadPlus; break;
+        case WXK_NUMPAD_SUBTRACT:  keycode = kVK_ANSI_KeypadMinus; break;
+        case WXK_NUMPAD_DECIMAL:   keycode = kVK_ANSI_KeypadDecimal; break;
+        case WXK_NUMPAD_DIVIDE:    keycode = kVK_ANSI_KeypadDivide; break;
+
+        default: wxLogDebug( "Unrecognised keycode %d", code );
     }
-    CFRelease(event);
+
+    return keycode;
 }
 
+} // anonymous namespace
+
 bool wxUIActionSimulator::MouseDown(int button)
 {
-    CGPoint pos;
-    int x, y;
-    wxGetMousePosition(&x, &y);
-    pos.x = x;
-    pos.y = y;
     CGEventType type = CGEventTypeForMouseButton(button, true);
-    CGEventRef event = CGEventCreateMouseEvent(NULL, type, pos, button);
+    wxCFRef<CGEventRef> event(
+            CGEventCreateMouseEvent(NULL, type, GetMousePosition(), button));
+
+    if ( !event )
+        return false;
+
     CGEventSetType(event, type);
+    CGEventPost(tap, event);
 
-    if (event)
-    {
-        CGEventPost(tap, event);
-    }
-    CFRelease(event);
     return true;
 }
 
@@ -78,56 +208,60 @@ bool wxUIActionSimulator::MouseMove(long x, long y)
     CGPoint pos;
     pos.x = x;
     pos.y = y;
+
     CGEventType type = kCGEventMouseMoved;
-    CGEventRef event = CGEventCreateMouseEvent(NULL, type, pos, kCGMouseButtonLeft);
-    CGEventSetType(event, type);
+    wxCFRef<CGEventRef> event(
+            CGEventCreateMouseEvent(NULL, type, pos, kCGMouseButtonLeft));
 
-    if (event)
-    {
-        CGEventPost(tap, event);
-    }
-    CFRelease(event);
+    if ( !event )
+        return false;
+
+    CGEventSetType(event, type);
+    CGEventPost(tap, event);
 
     return true;
 }
 
 bool wxUIActionSimulator::MouseUp(int button)
 {
-    CGPoint pos;
-    int x, y;
-    wxGetMousePosition(&x, &y);
-    pos.x = x;
-    pos.y = y;
     CGEventType type = CGEventTypeForMouseButton(button, false);
-    CGEventRef event = CGEventCreateMouseEvent(NULL, type, pos, button);
-    CGEventSetType(event, type);
+    wxCFRef<CGEventRef> event(
+            CGEventCreateMouseEvent(NULL, type, GetMousePosition(), button));
 
-    if (event)
-    {
-        CGEventPost(tap, event);
-    }
-    CFRelease(event);
+    if ( !event )
+        return false;
+
+    CGEventSetType(event, type);
+    CGEventPost(tap, event);
 
     return true;
 }
 
-bool wxUIActionSimulator::Key(int keycode, bool isDown, bool shiftDown, bool cmdDown, bool altDown)
+bool wxUIActionSimulator::DoKey(int keycode, int modifiers, bool isDown)
 {
-    if (shiftDown)
-        SendCharCode((CGCharCode)56, true);
-    if (altDown)
-        SendCharCode((CGCharCode)58, true);
-    if (cmdDown)
-        SendCharCode((CGCharCode)55, true);
-
-    SendCharCode((CGCharCode)keycode, isDown);
-
-    if (shiftDown)
-        SendCharCode((CGCharCode)56, false);
-    if (altDown)
-        SendCharCode((CGCharCode)58, false);
-    if (cmdDown)
-        SendCharCode((CGCharCode)55, false);
+    if (isDown)
+    {
+        if (modifiers & wxMOD_SHIFT)
+            SendCharCode(kVK_Shift, true);
+        if (modifiers & wxMOD_ALT)
+            SendCharCode(kVK_Option, true);
+        if (modifiers & wxMOD_CMD)
+            SendCharCode(kVK_Command, true);
+    }
+
+    CGKeyCode cgcode = wxCharCodeWXToOSX((wxKeyCode)keycode);
+    if ( !SendCharCode(cgcode, isDown) )
+        return false;
+
+    if(!isDown)
+    {
+        if (modifiers & wxMOD_SHIFT)
+            SendCharCode(kVK_Shift, false);
+        if (modifiers & wxMOD_ALT)
+            SendCharCode(kVK_Option, false);
+        if (modifiers & wxMOD_CMD)
+            SendCharCode(kVK_Command, false);
+    }
 
     return true;
 }
index 778e9bbc38c1d112a752bb0a7566f1a491e32513..975a65fc1b59d2cff4b1f34c034e2b1d42876834 100644 (file)
@@ -1,11 +1,13 @@
 /////////////////////////////////////////////////////////////////////////////
 // Name:        src/unix/uiactionx11.cpp
 // Purpose:     wxUIActionSimulator implementation
-// Author:      Kevin Ollivier
+// Author:      Kevin Ollivier, Steven Lamerton, Vadim Zeitlin
 // Modified by:
 // Created:     2010-03-06
 // RCS-ID:      $Id: menu.cpp 54129 2008-06-11 19:30:52Z SC $
 // Copyright:   (c) Kevin Ollivier
+//              (c) 2010 Steven Lamerton
+//              (c) 2010 Vadim Zeitlin
 // Licence:     wxWindows licence
 /////////////////////////////////////////////////////////////////////////////
 
 
 #include "wx/uiaction.h"
 
-#include <X11/Xlib.h>
 #include <X11/Xutil.h>
-#include <X11/extensions/XTest.h>
+
+#include "wx/unix/utilsx11.h"
+
+namespace
+{
 
 void SendButtonEvent(int button, bool isDown)
 {
-    int xbutton = 0;
+    int xbutton;
     switch (button)
     {
         case wxMOUSE_BTN_LEFT:
             xbutton = 1;
             break;
-        case wxMOUSE_BTN_RIGHT:
+        case wxMOUSE_BTN_MIDDLE:
             xbutton = 2;
             break;
-        case wxMOUSE_BTN_MIDDLE:
+        case wxMOUSE_BTN_RIGHT:
             xbutton = 3;
             break;
         default:
             wxFAIL_MSG("Unsupported button passed in.");
+            return;
     }
 
-    XEvent event;
-
-    Display *display = XOpenDisplay(0);
-    wxASSERT_MSG(display, "No display available!");
+    wxX11Display display;
+    wxCHECK_RET(display, "No display available!");
 
+    XEvent event;
     memset(&event, 0x00, sizeof(event));
 
-    if (isDown)
-        event.type = ButtonPress;
-    else
-        event.type = ButtonRelease;
-
+    event.type = isDown ? ButtonPress : ButtonRelease;
     event.xbutton.button = xbutton;
     event.xbutton.same_screen = True;
 
-    XQueryPointer(display, RootWindow(display, DefaultScreen(display)), &event.xbutton.root, &event.xbutton.window, &event.xbutton.x_root, &event.xbutton.y_root, &event.xbutton.x, &event.xbutton.y, &event.xbutton.state);
+    XQueryPointer(display, display.DefaultRoot(),
+                  &event.xbutton.root, &event.xbutton.window,
+                  &event.xbutton.x_root, &event.xbutton.y_root,
+                  &event.xbutton.x, &event.xbutton.y, &event.xbutton.state);
     event.xbutton.subwindow = event.xbutton.window;
 
     while (event.xbutton.subwindow)
     {
         event.xbutton.window = event.xbutton.subwindow;
-        XQueryPointer(display, event.xbutton.window, &event.xbutton.root, &event.xbutton.subwindow, &event.xbutton.x_root, &event.xbutton.y_root, &event.xbutton.x, &event.xbutton.y, &event.xbutton.state);
+        XQueryPointer(display, event.xbutton.window,
+                      &event.xbutton.root, &event.xbutton.subwindow,
+                      &event.xbutton.x_root, &event.xbutton.y_root,
+                      &event.xbutton.x, &event.xbutton.y, &event.xbutton.state);
     }
 
     XSendEvent(display, PointerWindow, True, 0xfff, &event);
-    XFlush(display);
-    XCloseDisplay(display);
 }
 
+} // anonymous namespace
+
 bool wxUIActionSimulator::MouseDown(int button)
 {
     SendButtonEvent(button, true);
@@ -74,12 +81,12 @@ bool wxUIActionSimulator::MouseDown(int button)
 
 bool wxUIActionSimulator::MouseMove(long x, long y)
 {
-    Display *display = XOpenDisplay(0);
+    wxX11Display display;
     wxASSERT_MSG(display, "No display available!");
-    Window root = DefaultRootWindow(display);
+
+    Window root = display.DefaultRoot();
     XWarpPointer(display, None, root, 0, 0, 0, 0, x, y);
-    XFlush(display);
-    XCloseDisplay(display);
+
     return true;
 }
 
@@ -89,37 +96,61 @@ bool wxUIActionSimulator::MouseUp(int button)
     return true;
 }
 
-bool wxUIActionSimulator::Key(int keycode, bool isDown, bool WXUNUSED(shiftDown), bool WXUNUSED(cmdDown), bool WXUNUSED(altDown))
+bool wxUIActionSimulator::DoKey(int keycode, int modifiers, bool isDown)
 {
-    Display *display = XOpenDisplay(0);
-    wxASSERT_MSG(display, "No display available!");
+    wxX11Display display;
+    wxCHECK_MSG(display, false, "No display available!");
 
-    XKeyEvent event;
-    int mask = 0xfff;
-    memset(&event, 0x00, sizeof(event));
+    int mask, type;
 
-    if (isDown) {
-        event.type = KeyPress;
+    if ( isDown )
+    {
+        type = KeyPress;
         mask = KeyPressMask;
     }
-    else {
-        event.type = KeyRelease;
+    else
+    {
+        type = KeyRelease;
         mask = KeyReleaseMask;
     }
-    event.same_screen = True;
 
-    XQueryPointer(display, RootWindow(display, DefaultScreen(display)), &event.root, &event.window, &event.x_root, &event.y_root, &event.x, &event.y, &event.state);
-    event.subwindow = event.window;
+    WXKeySym xkeysym = wxCharCodeWXToX(keycode);
+    KeyCode xkeycode = XKeysymToKeycode(display, xkeysym);
+    if ( xkeycode == NoSymbol )
+        return false;
 
-    while (event.subwindow)
-    {
-        event.window = event.subwindow;
-        XQueryPointer(display, event.window, &event.root, &event.subwindow, &event.x_root, &event.y_root, &event.x, &event.y, &event.state);
-    }
+    Window focus;
+    int revert;
+    XGetInputFocus(display, &focus, &revert);
+    if (focus == None)
+        return false;
+
+    int mod = 0;
+
+    if (modifiers & wxMOD_SHIFT)
+        mod |= ShiftMask;
+    //Mod1 is alt in the vast majority of cases
+    if (modifiers & wxMOD_ALT)
+        mod |= Mod1Mask;
+    if (modifiers & wxMOD_CMD)
+        mod |= ControlMask;
+
+    XKeyEvent event;
+    event.display = display;
+    event.window = focus;
+    event.root = DefaultRootWindow(event.display);
+    event.subwindow = None;
+    event.time = CurrentTime;
+    event.x = 1;
+    event.y = 1;
+    event.x_root = 1;
+    event.y_root = 1;
+    event.same_screen = True;
+    event.type = type;
+    event.state = mod;
+    event.keycode = xkeycode;
 
-    XSendEvent(display, PointerWindow, True, mask, (XEvent*) &event);
-    XFlush(display);
-    XCloseDisplay(display);
+    XSendEvent(event.display, event.window, True, mask, (XEvent*) &event);
 
     return true;
 }
index 25f61e10174086c345197ad139e0bb3498e3572b..63a320083168db6360deb8099877a9cc91ac3aac 100644 (file)
@@ -537,7 +537,7 @@ void wxSetFullScreenStateX11(WXDisplay* display, WXWindow rootWindow,
 
 // FIXME what about tables??
 
-int wxCharCodeXToWX(KeySym keySym)
+int wxCharCodeXToWX(WXKeySym keySym)
 {
     int id;
     switch (keySym)
@@ -717,9 +717,9 @@ int wxCharCodeXToWX(KeySym keySym)
     return id;
 }
 
-KeySym wxCharCodeWXToX(int id)
+WXKeySym wxCharCodeWXToX(int id)
 {
-    KeySym keySym;
+    WXKeySym keySym;
 
     switch (id)
     {