Added standard bus mouse support and inproved existing InPort mouse support

(Ben Lunt). Added new mouse type choice 'inport' for the existing one and changed
'bus' type to the new standard bus mouse,
This commit is contained in:
Volker Ruppert 2016-03-31 17:24:34 +00:00
parent e4832af5ab
commit 45232b1860
10 changed files with 262 additions and 104 deletions

View File

@ -488,9 +488,9 @@ vgaromimage: file=$BXSHARE/VGABIOS-lgpl-latest
# With the mouse type option you can select the type of mouse to emulate.
# The default value is 'ps2'. The other choices are 'imps2' (wheel mouse
# on PS/2), 'serial', 'serial_wheel', 'serial_msys' (one com port requires
# setting 'mode=mouse') and 'bus' (if present). To connect a mouse to a
# USB port, see the 'usb_uhci', 'usb_ohci' or 'usb_xhci' options (requires
# PCI and USB support).
# setting 'mode=mouse') 'inport' and 'bus' (if present). To connect a mouse
# to a USB port, see the 'usb_uhci', 'usb_ohci' or 'usb_xhci' options
# (requires PCI and USB support).
#
# ENABLED:
# The Bochs gui creates mouse "events" unless the 'enabled' option is

View File

@ -2,7 +2,7 @@
// $Id$
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2002-2015 The Bochs Project
// Copyright (C) 2002-2016 The Bochs Project
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@ -1031,6 +1031,7 @@ void bx_init_options()
"ps2",
"imps2",
#if BX_SUPPORT_BUSMOUSE
"inport",
"bus",
#endif
"serial",

2
bochs/configure vendored
View File

@ -1785,7 +1785,7 @@ Optional Features:
--enable-es1370 enable ES1370 soundcard support (no)
--enable-gameport enable standard PC gameport support (yes, if
soundcard present)
--enable-busmouse enable Busmouse support (InPort)
--enable-busmouse enable Busmouse support (InPort & Standard)
--enable-docbook build the Docbook documentation (yes, if docbook
present)
--enable-xpm enable the check for XPM support (yes)

View File

@ -2084,7 +2084,7 @@ BUSM_OBJS=''
bx_busmouse=0
AC_MSG_CHECKING(for Busmouse support)
AC_ARG_ENABLE(busmouse,
AS_HELP_STRING([--enable-busmouse], [enable Busmouse support (InPort)]),
AS_HELP_STRING([--enable-busmouse], [enable Busmouse support (InPort & Standard)]),
[if test "$enableval" = yes; then
AC_MSG_RESULT(yes)
AC_DEFINE(BX_SUPPORT_BUSMOUSE, 1)

View File

@ -3848,7 +3848,7 @@ With the mouse type option you can select the type of mouse to emulate.
The default value is 'ps2'. The other choices are 'imps2' (wheel mouse
on PS/2), 'serial', 'serial_wheel', 'serial_msys' (one com port requires
setting 'mode=mouse', see <link linkend="bochsopt-com">com option</link>)
and 'bus' (if present). To connect a mouse to a USB port, see the
'inport' and 'bus' (if present). To connect a mouse to a USB port, see the
<link linkend="bochsopt-usb-uhci">usb_uhci</link>, 'usb_ohci 'or
'usb_xhci' option (requires PCI and USB support).
</para>

View File

@ -1,5 +1,5 @@
.\"Document Author: Timothy R. Butler - tbutler@uninetsolutions.com"
.TH bochsrc 5 "1 Sep 2015" "bochsrc" "The Bochs Project"
.TH bochsrc 5 "31 Mar 2016" "bochsrc" "The Bochs Project"
.\"SKIP_SECTION"
.SH NAME
bochsrc \- Configuration file for Bochs.
@ -547,9 +547,9 @@ type
With the mouse type option you can select the type of mouse to emulate.
The default value is 'ps2'. The other choices are 'imps2' (wheel mouse
on PS/2), 'serial', 'serial_wheel', 'serial_msys' (one com port requires
setting 'mode=mouse') and 'bus' (if present). To connect a mouse to a
USB port, see the 'usb_uhci', 'usb_ohci' or 'usb_xhci' option (requires
PCI and USB support).
setting 'mode=mouse') 'inport' and 'bus' (if present). To connect a mouse
to a USB port, see the 'usb_uhci', 'usb_ohci' or 'usb_xhci' option
(requires PCI and USB support).
enabled

View File

@ -2,7 +2,7 @@
// $Id$
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001-2015 The Bochs Project
// Copyright (C) 2001-2016 The Bochs Project
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@ -482,6 +482,7 @@ enum {
BX_MOUSE_TYPE_PS2,
BX_MOUSE_TYPE_IMPS2,
#if BX_SUPPORT_BUSMOUSE
BX_MOUSE_TYPE_INPORT,
BX_MOUSE_TYPE_BUS,
#endif
BX_MOUSE_TYPE_SERIAL,

View File

@ -2,7 +2,7 @@
// $Id$
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2004-2014 The Bochs Project
// Copyright (C) 2004-2016 The Bochs Project
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@ -19,7 +19,8 @@
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
// Initial code by Ben Lunt 'fys frontiernet net'
// Initial/additional code by Ben Lunt 'fys at fysnet dot net'
// http://www.fysnet.net
// Define BX_PLUGGABLE in files that can be compiled into plugins. For
// platforms that require a special tag on exported symbols, BX_PLUGGABLE
@ -35,17 +36,48 @@
bx_busm_c *theBusMouse = NULL;
// There is a difference between older hardware and newer hardware.
// Set this flag to indicate older hardware. I will explain the difference
// at each item this flag is used.
#define LEGACY_BUSMOUSE 0
#define BUS_MOUSE_IRQ 5
#define IRQ_MASK ((1<<5) >> BUS_MOUSE_IRQ)
#define PORT_CONTROL 0x023C
#define PORT_DATA 0x023D
#define PORT_SIGNATURE 0x023E
#define PORT_CONFIG 0x023F
// MS Inport Bus Mouse Adapter
#define INP_PORT_CONTROL 0x023C
#define INP_PORT_DATA 0x023D
#define INP_PORT_SIGNATURE 0x023E
#define INP_PORT_CONFIG 0x023F
#define INP_CTRL_READ_BUTTONS 0x00
#define INP_CTRL_READ_X 0x01
#define INP_CTRL_READ_Y 0x02
#define INP_CTRL_COMMAND 0x07
#define INP_CTRL_RAISE_IRQ 0x16
#define INP_CTRL_RESET 0x80
#define INP_HOLD_COUNTER (1 << 5)
#define INP_ENABLE_IRQ (1 << 0)
// MS/Logictech Standard Bus Mouse Adapter
#define BUSM_PORT_DATA 0x023C
#define BUSM_PORT_SIGNATURE 0x023D
#define BUSM_PORT_CONTROL 0x023E
#define BUSM_PORT_CONFIG 0x023F
#define HOLD_COUNTER (1 << 7)
#define READ_X (0 << 6)
#define READ_Y (1 << 6)
#define READ_LOW (0 << 5)
#define READ_HIGH (1 << 5)
#define DISABLE_IRQ (1 << 4)
#define READ_X_LOW (READ_X | READ_LOW)
#define READ_X_HIGH (READ_X | READ_HIGH)
#define READ_Y_LOW (READ_Y | READ_LOW)
#define READ_Y_HIGH (READ_Y | READ_HIGH)
#define BUSM_CTRL_READ_BUTTONS 0x00
#define BUSM_CTRL_READ_X 0x01
#define BUSM_CTRL_READ_Y 0x02
#define BUSM_CTRL_COMMAND 0x07
int CDECL libbusmouse_LTX_plugin_init(plugin_t *plugin, plugintype_t type, int argc, char *argv[])
{
@ -76,6 +108,8 @@ void bx_busm_c::init(void)
{
BX_DEBUG(("Init $Id$"));
BX_BUSM_THIS type = SIM->get_param_enum(BXPN_MOUSE_TYPE)->get();
DEV_register_irq(BUS_MOUSE_IRQ, "Bus Mouse");
// Call our timer routine at 30hz
@ -95,13 +129,23 @@ void bx_busm_c::init(void)
BX_BUSM_THIS current_y =
BX_BUSM_THIS current_b = 0;
BX_BUSM_THIS control_val = 0; // the control port value
if (BX_BUSM_THIS type == BX_MOUSE_TYPE_INPORT) {
BX_BUSM_THIS control_val = 0; // the control port value
BX_BUSM_THIS mouse_buttons_last = 0;
} else {
BX_BUSM_THIS control_val = 0x1f; // the control port value
BX_BUSM_THIS config_val = 0x0e; // the config port value
BX_BUSM_THIS sig_val = 0; // the signature port value
}
BX_BUSM_THIS command_val = 0; // command byte
BX_BUSM_THIS sig_port_sequ = 0; // signature byte toggle
BX_BUSM_THIS toggle_counter = 0; // signature byte / IRQ bit toggle
BX_BUSM_THIS interrupts = 0; // interrupts off
BX_BUSM_THIS needs_update = 0;
BX_INFO(("BusMouse initialized"));
if (BX_BUSM_THIS type == BX_MOUSE_TYPE_INPORT) {
BX_INFO(("MS Inport BusMouse initialized"));
} else {
BX_INFO(("Standard MS/Logitech BusMouse initialized"));
}
}
void bx_busm_c::register_state(void)
@ -110,15 +154,18 @@ void bx_busm_c::register_state(void)
BXRS_DEC_PARAM_FIELD(list, mouse_delayed_dx, BX_BUSM_THIS mouse_delayed_dx);
BXRS_DEC_PARAM_FIELD(list, mouse_delayed_dy, BX_BUSM_THIS mouse_delayed_dy);
BXRS_HEX_PARAM_FIELD(list, mouse_buttons, BX_BUSM_THIS mouse_buttons);
BXRS_HEX_PARAM_FIELD(list, mouse_buttons_last, BX_BUSM_THIS mouse_buttons_last);
BXRS_HEX_PARAM_FIELD(list, current_x, BX_BUSM_THIS current_x);
BXRS_HEX_PARAM_FIELD(list, current_y, BX_BUSM_THIS current_y);
BXRS_HEX_PARAM_FIELD(list, current_b, BX_BUSM_THIS current_b);
BXRS_HEX_PARAM_FIELD(list, control_val, BX_BUSM_THIS control_val);
BXRS_HEX_PARAM_FIELD(list, command_val, BX_BUSM_THIS command_val);
BXRS_PARAM_BOOL(list, sig_port_sequ, BX_BUSM_THIS sig_port_sequ);
BXRS_HEX_PARAM_FIELD(list, toggle_counter, BX_BUSM_THIS toggle_counter);
BXRS_PARAM_BOOL(list, interrupts, BX_BUSM_THIS interrupts);
BXRS_PARAM_BOOL(list, needs_update, BX_BUSM_THIS needs_update);
BXRS_HEX_PARAM_FIELD(list, config_val, BX_BUSM_THIS config_val);
BXRS_HEX_PARAM_FIELD(list, sig_val, BX_BUSM_THIS sig_val);
}
// static IO port read callback handler
@ -138,39 +185,86 @@ Bit32u bx_busm_c::read(Bit32u address, unsigned io_len)
Bit8u value = 0;
switch (address) {
case PORT_CONTROL:
value = BX_BUSM_THIS control_val;
break;
case PORT_DATA:
switch (BX_BUSM_THIS control_val) {
case BUSM_CTRL_READ_BUTTONS:
value = BX_BUSM_THIS current_b;
break;
case BUSM_CTRL_READ_X:
value = BX_BUSM_THIS current_x;
break;
case BUSM_CTRL_READ_Y:
value = BX_BUSM_THIS current_y;
break;
case BUSM_CTRL_COMMAND:
value = BX_BUSM_THIS command_val;
break;
default:
BX_ERROR(("Reading data port in unsupported mode 0x%02x", BX_BUSM_THIS control_val));
}
break;
case PORT_SIGNATURE:
if (!BX_BUSM_THIS sig_port_sequ) {
value = 0xDE;
} else {
value = 0x22; // Manufacturer id ?
}
BX_BUSM_THIS sig_port_sequ ^= 1;
break;
case PORT_CONFIG:
BX_ERROR(("Unsupported read from port 0x%04x", address));
break;
if (BX_BUSM_THIS type == BX_MOUSE_TYPE_INPORT) {
switch (address) {
case INP_PORT_CONTROL:
value = BX_BUSM_THIS control_val;
break;
case INP_PORT_DATA:
switch (BX_BUSM_THIS command_val) {
case INP_CTRL_READ_BUTTONS:
value = BX_BUSM_THIS current_b;
#if !LEGACY_BUSMOUSE
value |= 0x40; // Newer Logitech mouse drivers look for bit 6 set
#endif
break;
case INP_CTRL_READ_X:
value = BX_BUSM_THIS current_x;
break;
case INP_CTRL_READ_Y:
value = BX_BUSM_THIS current_y;
break;
case INP_CTRL_COMMAND:
value = BX_BUSM_THIS control_val;
break;
default:
BX_ERROR(("Reading data port in unsupported mode 0x%02x", BX_BUSM_THIS control_val));
}
break;
case INP_PORT_SIGNATURE:
if (!BX_BUSM_THIS toggle_counter) {
value = 0xDE;
} else {
value = 0x12; // Manufacturer id ?
}
BX_BUSM_THIS toggle_counter ^= 1;
break;
case INP_PORT_CONFIG:
BX_ERROR(("Unsupported read from port 0x%04x", address));
break;
}
} else {
switch (address) {
case BUSM_PORT_CONTROL:
value = BX_BUSM_THIS control_val;
// this is to allow the driver to see which IRQ the card has "jumpered"
// only happens if IRQ's are enabled
BX_BUSM_THIS control_val |= 0x0F;
if ((BX_BUSM_THIS toggle_counter > 0x3FF)
// newer hardware only changes the bit when interrupts are on
// older hardware changes the bit no matter if interrupts are on or not
#if !LEGACY_BUSMOUSE
&& BX_BUSM_THIS interrupts
#endif
)
BX_BUSM_THIS control_val &= ~IRQ_MASK;
BX_BUSM_THIS toggle_counter = (BX_BUSM_THIS toggle_counter + 1) & 0x7FF;
break;
case BUSM_PORT_DATA:
switch (BX_BUSM_THIS control_val & 0x60) {
case READ_X_LOW:
value = BX_BUSM_THIS current_x & 0x0F;
break;
case READ_X_HIGH:
value = (BX_BUSM_THIS current_x >> 4) & 0x0F;
break;
case READ_Y_LOW:
value = BX_BUSM_THIS current_y & 0x0F;
break;
case READ_Y_HIGH:
value = ((BX_BUSM_THIS current_b ^ 7) << 5) | ((BX_BUSM_THIS current_y >> 4) & 0x0F);
break;
default:
BX_ERROR(("Reading data port in unsupported mode 0x%02x", BX_BUSM_THIS control_val));
}
break;
case BUSM_PORT_CONFIG:
value = BX_BUSM_THIS config_val;
break;
case BUSM_PORT_SIGNATURE:
value = BX_BUSM_THIS sig_val;
break;
}
}
BX_DEBUG(("read from address 0x%04x, value = 0x%02x ", address, value));
@ -196,38 +290,65 @@ void bx_busm_c::write(Bit32u address, Bit32u value, unsigned io_len)
BX_DEBUG(("write to address 0x%04x, value = 0x%02x ", address, value));
switch (address) {
case PORT_CONTROL:
BX_BUSM_THIS control_val = value & 0x07;
break;
case PORT_DATA:
if (BX_BUSM_THIS control_val == BUSM_CTRL_COMMAND) {
if ((value & 0x20) == 0x20) {
BX_BUSM_THIS update_mouse_data();
} else {
DEV_pic_lower_irq(BUS_MOUSE_IRQ);
}
if (BX_BUSM_THIS type == BX_MOUSE_TYPE_INPORT) {
switch (address) {
case INP_PORT_CONTROL:
switch (value) {
case 0x10: // interrupts off
BX_BUSM_THIS interrupts = 0;
case INP_CTRL_RESET:
BX_BUSM_THIS control_val = 0;
BX_BUSM_THIS command_val = 0;
break;
case 0x09:
case 0x11: // interrupts on
BX_BUSM_THIS interrupts = 1;
case INP_CTRL_COMMAND:
case INP_CTRL_READ_BUTTONS:
case INP_CTRL_READ_X:
case INP_CTRL_READ_Y:
BX_BUSM_THIS command_val = value;
break;
case 0x16: // test irq
DEV_pic_raise_irq(BUS_MOUSE_IRQ);
case 0x87: // ???????
BX_BUSM_THIS control_val = 0;
BX_BUSM_THIS command_val = 0x07;
break;
default:
BX_ERROR(("Unsupported command written to port 0x%04x (value = 0x%02x)", address, value));
}
BX_BUSM_THIS command_val = value;
} else {
BX_ERROR(("Value 0x%02x written in supported mode 0x%02x", value, BX_BUSM_THIS control_val));
}
break;
case PORT_SIGNATURE:
case PORT_CONFIG:
BX_ERROR(("Unsupported write to port 0x%04x (value = 0x%02x)", address, value));
break;
break;
case INP_PORT_DATA:
DEV_pic_lower_irq(BUS_MOUSE_IRQ);
if (value == INP_CTRL_RAISE_IRQ) {
DEV_pic_raise_irq(BUS_MOUSE_IRQ);
} else {
switch (BX_BUSM_THIS command_val) {
case INP_CTRL_COMMAND:
BX_BUSM_THIS control_val = value;
BX_BUSM_THIS interrupts = (value & INP_ENABLE_IRQ) > 0;
break;
default:
BX_ERROR(("Unsupported write to port 0x%04x (value = 0x%02x)", address, value));
}
}
break;
case INP_PORT_SIGNATURE:
case INP_PORT_CONFIG:
BX_ERROR(("Unsupported write to port 0x%04x (value = 0x%02x)", address, value));
break;
}
} else {
switch (address) {
case BUSM_PORT_CONTROL:
BX_BUSM_THIS control_val = value | 0x0F;
BX_BUSM_THIS interrupts = (value & DISABLE_IRQ) == 0;
DEV_pic_lower_irq(BUS_MOUSE_IRQ);
break;
case BUSM_PORT_CONFIG:
BX_BUSM_THIS config_val = value;
break;
case BUSM_PORT_SIGNATURE:
BX_BUSM_THIS sig_val = value;
break;
case BUSM_PORT_DATA:
BX_ERROR(("Unsupported write to port 0x%04x (value = 0x%02x)", address, value));
break;
}
}
}
@ -251,14 +372,37 @@ void bx_busm_c::mouse_enq(int delta_x, int delta_y, int delta_z, unsigned button
BX_BUSM_THIS mouse_delayed_dx += delta_x;
BX_BUSM_THIS mouse_delayed_dy -= delta_y;
BX_BUSM_THIS mouse_buttons = (Bit8u)(0x40 | ((button_state & 1) << 2) |
((button_state & 2) >> 1));
BX_BUSM_THIS needs_update = 1;
// change button_state MRL to LMR
BX_BUSM_THIS mouse_buttons = (Bit8u) (((button_state & 1) << 2) |
((button_state & 4) >> 1) | ((button_state & 2) >> 1));
if (BX_BUSM_THIS type == BX_MOUSE_TYPE_INPORT) {
// The InPort button status is as so
// 00lmrLMR
// where lower case letters are changed in state
// where upper case letters are the state of that button
// TODO:
// Bochs needs to call this function one more time on a button release so that
// bits 5:3 get cleared. However, as is, it works with the code I tested it on,
// so no worries, so far.
if ((BX_BUSM_THIS mouse_buttons & (1<<2)) ||
((BX_BUSM_THIS mouse_buttons_last & (1<<2)) && !(BX_BUSM_THIS mouse_buttons & (1<<2))))
BX_BUSM_THIS mouse_buttons |= (1<<5);
if ((BX_BUSM_THIS mouse_buttons & (1<<1)) ||
((BX_BUSM_THIS mouse_buttons_last & (1<<1)) && !(BX_BUSM_THIS mouse_buttons & (1<<1))))
BX_BUSM_THIS mouse_buttons |= (1<<4);
if ((BX_BUSM_THIS mouse_buttons & (1<<0)) ||
((BX_BUSM_THIS mouse_buttons_last & (1<<0)) && !(BX_BUSM_THIS mouse_buttons & (1<<0))))
BX_BUSM_THIS mouse_buttons |= (1<<3);
BX_BUSM_THIS mouse_buttons_last = BX_BUSM_THIS mouse_buttons;
}
}
void bx_busm_c::update_mouse_data()
{
int delta_x, delta_y;
bx_bool hold;
if (BX_BUSM_THIS mouse_delayed_dx > 127) {
delta_x = 127;
@ -280,14 +424,17 @@ void bx_busm_c::update_mouse_data()
delta_y = BX_BUSM_THIS mouse_delayed_dy;
BX_BUSM_THIS mouse_delayed_dy = 0;
}
if ((BX_BUSM_THIS mouse_delayed_dx == 0) &&
(BX_BUSM_THIS mouse_delayed_dy == 0)) {
BX_BUSM_THIS needs_update = 0;
}
BX_BUSM_THIS current_x = (Bit8u) delta_x;
BX_BUSM_THIS current_y = (Bit8u) delta_y;
BX_BUSM_THIS current_b = mouse_buttons;
if (BX_BUSM_THIS type == BX_MOUSE_TYPE_INPORT) {
hold = (BX_BUSM_THIS control_val & INP_HOLD_COUNTER) > 0;
} else {
hold = (BX_BUSM_THIS control_val & HOLD_COUNTER) > 0;
}
if (!hold) {
BX_BUSM_THIS current_x = (Bit8u) delta_x;
BX_BUSM_THIS current_y = (Bit8u) delta_y;
BX_BUSM_THIS current_b = BX_BUSM_THIS mouse_buttons;
}
}
void bx_busm_c::timer_handler(void *this_ptr)
@ -299,9 +446,14 @@ void bx_busm_c::timer_handler(void *this_ptr)
// Called at 30hz
void bx_busm_c::busm_timer(void)
{
// The controller updates the data on every interrupt
// We just don't copy it to the current_X if the 'hold' bit is set
BX_BUSM_THIS update_mouse_data();
// if interrupts are on, fire the interrupt
if (BX_BUSM_THIS interrupts && BX_BUSM_THIS needs_update) {
if (BX_BUSM_THIS interrupts) {
DEV_pic_raise_irq(BUS_MOUSE_IRQ);
BX_DEBUG(("Interrupt Fired..."));
}
}

View File

@ -2,7 +2,7 @@
// $Id$
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2004-2013 The Bochs Project
// Copyright (C) 2004-2016 The Bochs Project
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@ -57,18 +57,21 @@ private:
Bit32u read(Bit32u address, unsigned io_len);
#endif
int type;
int timer_index; // our timer index
int mouse_delayed_dx;
int mouse_delayed_dy;
Bit8u mouse_buttons;
Bit8u mouse_buttons_last;
Bit8u current_x, current_y, current_b;
Bit8u control_val;
Bit8u command_val; // current command val
Bit8u config_val;
Bit8u sig_val;
Bit16u toggle_counter;
bx_bool interrupts; // 0 or 1. interrupts off or on.
bx_bool sig_port_sequ; // A register read rotates between two values? 0xDE and Hardware ID?
bx_bool needs_update; // update of mouse data register required
};
#endif // BX_SUPPORT_BUSMOUSE

View File

@ -2,7 +2,7 @@
// $Id$
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2002-2015 The Bochs Project
// Copyright (C) 2002-2016 The Bochs Project
//
// I/O port handlers API Copyright (C) 2003 by Frank Cornelis
//
@ -220,7 +220,8 @@ void bx_devices_c::init(BX_MEM_C *newmem)
#endif
PLUG_load_plugin(keyboard, PLUGTYPE_STANDARD);
#if BX_SUPPORT_BUSMOUSE
if (mouse_type == BX_MOUSE_TYPE_BUS) {
if ((mouse_type == BX_MOUSE_TYPE_INPORT) ||
(mouse_type == BX_MOUSE_TYPE_BUS)) {
PLUG_load_plugin(busmouse, PLUGTYPE_OPTIONAL);
}
#endif