From 24d88d2d28d6e84ad51beab95d7946fd1af334bd Mon Sep 17 00:00:00 2001 From: Bryce Denney Date: Wed, 18 Sep 2002 22:44:02 +0000 Subject: [PATCH] - implement mouse in wxWindows interface - All mouse events in the VGA window go to MyPanel::OnMouse. Middle mouse button and F12 both toggle mouse capture. OnMouse queues an event for the simulation thread to process. The simulation thread calls bx_devices.keyboard->mouse_motion() when it sees the event on the queue. - add IFDBG_VGA around some display debug code. All wx mouse debug code is controlled by IFDBG_MOUSE. - modified: gui/wx.cc gui/wxmain.cc gui/wxmain.h --- bochs/gui/wx.cc | 104 +++++++++++++++++++++++++++++++++++++------- bochs/gui/wxmain.cc | 4 +- bochs/gui/wxmain.h | 11 ++++- 3 files changed, 100 insertions(+), 19 deletions(-) diff --git a/bochs/gui/wx.cc b/bochs/gui/wx.cc index c51031c07..b17d4a567 100644 --- a/bochs/gui/wx.cc +++ b/bochs/gui/wx.cc @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////// -// $Id: wx.cc,v 1.22 2002-09-18 20:57:34 bdenney Exp $ +// $Id: wx.cc,v 1.23 2002-09-18 22:44:02 bdenney Exp $ ///////////////////////////////////////////////////////////////// // // wxWindows VGA display for Bochs. wx.cc implements a custom @@ -90,8 +90,9 @@ unsigned long num_events = 0; BEGIN_EVENT_TABLE(MyPanel, wxPanel) EVT_KEY_DOWN(MyPanel::OnKeyDown) EVT_KEY_UP(MyPanel::OnKeyUp) - EVT_PAINT(MyPanel::OnPaint) EVT_TIMER(-1, MyPanel::OnTimer) + EVT_PAINT(MyPanel::OnPaint) + EVT_MOUSE_EVENTS(MyPanel::OnMouse) END_EVENT_TABLE() MyPanel::MyPanel(wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style, const wxString& name) @@ -105,9 +106,9 @@ MyPanel::MyPanel(wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSi void MyPanel::OnTimer(wxCommandEvent& WXUNUSED(event)) { - wxLogDebug ("timer"); + IFDBG_VGA(wxLogDebug ("timer")); if (needRefresh) { - wxLogDebug ("painting"); + IFDBG_VGA(wxLogDebug ("painting")); wxPaintEvent unused; OnPaint (unused); } @@ -116,7 +117,7 @@ void MyPanel::OnTimer(wxCommandEvent& WXUNUSED(event)) void MyPanel::OnPaint(wxPaintEvent& WXUNUSED(event)) { wxPaintDC dc(this); - BX_INFO (("OnPaint")); + IFDBG_VGA (wxLogDebug ("OnPaint")); //PrepareDC(dc); IFDBG_VGA(wxLogDebug ("MyPanel::OnPaint trying to get lock. wxScreen=%p", wxScreen)); @@ -130,10 +131,83 @@ void MyPanel::OnPaint(wxPaintEvent& WXUNUSED(event)) needRefresh = false; } +void MyPanel::ToggleMouse () +{ + bx_param_bool_c *enable = SIM->get_param_bool (BXP_MOUSE_ENABLED); + bool en = ! enable->get (); + enable->set (en); + IFDBG_MOUSE (wxLogDebug ("now mouse is %sabled", en ? "en" : "dis")); + if (en) { + mouseSavedX = wxScreenX / 2; + mouseSavedY = wxScreenY / 2; + WarpPointer (mouseSavedX, mouseSavedY); + } +} + +void MyPanel::OnMouse(wxMouseEvent& event) +{ + long x,y; + event.GetPosition (&x, &y); + IFDBG_MOUSE ( + if (event.IsButton ()) { + wxLogDebug ("mouse button event at %d,%d", x, y); + } else if (event.Entering ()) { + wxLogDebug ("mouse entering at %d,%d", x, y); + } else if (event.Leaving ()) { + wxLogDebug ("mouse leaving at %d,%d", x, y); + } else if (event.Moving() || event.Dragging ()) { + wxLogDebug ("mouse moved to %d,%d", x, y); + } else { + wxLogDebug ("other mouse event at %d,%d", x, y); + } + ) + + if (event.MiddleDown ()) { + ToggleMouse (); + return; + } + + if (!SIM->get_param_bool(BXP_MOUSE_ENABLED)->get ()) + return; // mouse disabled, ignore the event + + // process buttons and motion together + Bit32u buttons; + buttons = event.LeftIsDown () ? 1 : 0; + buttons |= event.RightIsDown () ? 2 : 0; + if (x==mouseSavedX && y==mouseSavedY && !event.IsButton ()) { + // nothing happened. This could have been generated by the WarpPointer. + return; + } else { + if(num_events < MAX_EVENTS) { + wxCriticalSectionLocker lock(event_thread_lock); + Bit16s dx = x - mouseSavedX; + Bit16s dy = y - mouseSavedY; + IFDBG_MOUSE (wxLogDebug ("mouse moved by delta %d,%d", dx, dy)); + event_queue[num_events].type = BX_ASYNC_EVT_MOUSE; + event_queue[num_events].u.mouse.dx = dx; + event_queue[num_events].u.mouse.dy = -dy; + event_queue[num_events].u.mouse.buttons = buttons; + num_events++; + mouseSavedX = x; + mouseSavedY = y; + } else { + wxLogDebug ("mouse event skipped because event queue full"); + } + } + + mouseSavedX = wxScreenX / 2; + mouseSavedY = wxScreenY / 2; + WarpPointer (mouseSavedX, mouseSavedY); + // The WarpPointer moves the pointer back to the middle of the + // screen. This WILL produce another mouse motion event, which needs + // to be ignored. It will be ignored because the new motion event + // will move the cursor to (mouseSavedX, mouseSavedY). +} + void MyPanel::MyRefresh () { - BX_INFO (("set needRefresh=true")); + IFDBG_VGA (wxLogDebug ("set needRefresh=true")); needRefresh = true; } @@ -166,14 +240,8 @@ MyPanel::SaveConfiguration () void MyPanel::OnKeyDown(wxKeyEvent& event) { if(event.GetKeyCode() == WXK_F12) { - if(wxMouseCaptured) { - ReleaseMouse(); - wxMouseCaptured = FALSE; - } else { - CaptureMouse(); - wxMouseCaptured = TRUE; - } - return; + ToggleMouse (); + return; } wxCriticalSectionLocker lock(event_thread_lock); if(num_events < MAX_EVENTS) { @@ -627,7 +695,7 @@ bx_gui_c::specific_init(bx_gui_c *th, int argc, char **argv, unsigned tilewidth, int b,i,j; unsigned char fc, vc; - th->put("NGUI"); + th->put("WX "); if (bx_options.Oprivate_colormap->get ()) { BX_INFO(("private_colormap option ignored.")); } @@ -714,6 +782,12 @@ void bx_gui_c::handle_events(void) bx_devices.keyboard->gen_scancode(bx_key); } break; + case BX_ASYNC_EVT_MOUSE: + bx_devices.keyboard->mouse_motion ( + event_queue[i].u.mouse.dx, + event_queue[i].u.mouse.dy, + event_queue[i].u.mouse.buttons); + break; default: wxLogError ("handle_events received unhandled event type %d in queue", (int)event_queue[i].type); } diff --git a/bochs/gui/wxmain.cc b/bochs/gui/wxmain.cc index fa57d5ef0..f992599b6 100644 --- a/bochs/gui/wxmain.cc +++ b/bochs/gui/wxmain.cc @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////// -// $Id: wxmain.cc,v 1.49 2002-09-18 20:59:05 bdenney Exp $ +// $Id: wxmain.cc,v 1.50 2002-09-18 22:44:02 bdenney Exp $ ///////////////////////////////////////////////////////////////// // // wxmain.cc implements the wxWindows frame, toolbar, menus, and dialogs. @@ -344,7 +344,7 @@ MyFrame::MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size, // Omit config button because the whole wxWindows interface is like // one really big config button. //BX_ADD_TOOL(ID_Toolbar_Config, configbutton_xpm, "Runtime Configuration"); - BX_ADD_TOOL(ID_Toolbar_Mouse_en, mouse_xpm, "(Mouse Not Implemented Yet!)"); + BX_ADD_TOOL(ID_Toolbar_Mouse_en, mouse_xpm, "Enable/disable mouse\nAlso, middle mouse button does the same thing."); BX_ADD_TOOL(ID_Toolbar_User, userbutton_xpm, "Keyboard shortcut"); tb->Realize(); diff --git a/bochs/gui/wxmain.h b/bochs/gui/wxmain.h index 43a378279..4a80830fc 100644 --- a/bochs/gui/wxmain.h +++ b/bochs/gui/wxmain.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////// -// $Id: wxmain.h,v 1.25 2002-09-18 20:59:35 bdenney Exp $ +// $Id: wxmain.h,v 1.26 2002-09-18 22:44:02 bdenney Exp $ ///////////////////////////////////////////////////////////////// // This file defines variables and classes that the wxWindows .cc files // share. It should be included only by wx.cc and wxmain.cc. @@ -110,6 +110,9 @@ enum #define IFDBG_KEY(x) /* nothing */ //#define IFDBG_KEY(x) x +#define IFDBG_MOUSE(x) /* nothing */ +//#define IFDBG_MOUSE(x) x + #define IFDBG_EVENT(x) /* nothing */ //#define IFDBG_EVENT(x) x @@ -130,14 +133,18 @@ public: MyPanel(wxWindow* parent, wxWindowID id, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = wxTAB_TRAVERSAL, const wxString& name = "panel"); void OnKeyDown(wxKeyEvent& event); void OnKeyUp(wxKeyEvent& event); - void OnPaint(wxPaintEvent& event); void OnTimer(wxCommandEvent& event); + void OnPaint(wxPaintEvent& event); + void OnMouse(wxMouseEvent& event); void MyRefresh (); void ReadConfiguration (); void SaveConfiguration (); + void ToggleMouse (); private: bool needRefresh; wxTimer refreshTimer; + Bit16s mouseSavedX, mouseSavedY; + Bit32u centerX, centerY; DECLARE_EVENT_TABLE() };