- 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
This commit is contained in:
Bryce Denney 2002-09-18 22:44:02 +00:00
parent cfd549d7c0
commit 24d88d2d28
3 changed files with 100 additions and 19 deletions

View File

@ -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);
}

View File

@ -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();

View File

@ -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()
};