Support addition & removal of mouse & tablet input devices

This commit is contained in:
Daniel P. Berrange 2007-09-25 20:05:45 -04:00
parent 7f1d92b9d8
commit 8b2f0e5044
5 changed files with 938 additions and 8 deletions

View File

@ -46,7 +46,8 @@ DEFAULT_STORAGE_FILE_SIZE = 500
PAGE_INTRO = 0 PAGE_INTRO = 0
PAGE_DISK = 1 PAGE_DISK = 1
PAGE_NETWORK = 2 PAGE_NETWORK = 2
PAGE_SUMMARY = 3 PAGE_INPUT = 3
PAGE_SUMMARY = 4
class vmmAddHardware(gobject.GObject): class vmmAddHardware(gobject.GObject):
__gsignals__ = { __gsignals__ = {
@ -90,6 +91,8 @@ class vmmAddHardware(gobject.GObject):
if self.vm.get_connection().get_type().lower() == "qemu" and os.getuid() == 0: if self.vm.get_connection().get_type().lower() == "qemu" and os.getuid() == 0:
model.append(["Network card", gtk.STOCK_NETWORK, PAGE_NETWORK]) model.append(["Network card", gtk.STOCK_NETWORK, PAGE_NETWORK])
model.append(["Input device", gtk.STOCK_INDEX, PAGE_INPUT])
self.set_initial_state() self.set_initial_state()
def show(self): def show(self):
@ -137,6 +140,14 @@ class vmmAddHardware(gobject.GObject):
target_list.pack_start(text, True) target_list.pack_start(text, True)
target_list.add_attribute(text, 'text', 4) target_list.add_attribute(text, 'text', 4)
input_list = self.window.get_widget("input-type")
input_model = gtk.ListStore(str, str, str, bool)
input_list.set_model(input_model)
text = gtk.CellRendererText()
input_list.pack_start(text, True)
input_list.add_attribute(text, 'text', 0)
input_list.add_attribute(text, 'sensitive', 3)
def reset_state(self): def reset_state(self):
notebook = self.window.get_widget("create-pages") notebook = self.window.get_widget("create-pages")
notebook.set_current_page(0) notebook.set_current_page(0)
@ -178,6 +189,10 @@ class vmmAddHardware(gobject.GObject):
target_list = self.window.get_widget("target-device") target_list = self.window.get_widget("target-device")
target_list.set_active(-1) target_list.set_active(-1)
input_box = self.window.get_widget("input-type")
self.populate_input_model(input_box.get_model())
input_box.set_active(0)
def forward(self, ignore=None): def forward(self, ignore=None):
notebook = self.window.get_widget("create-pages") notebook = self.window.get_widget("create-pages")
@ -228,6 +243,13 @@ class vmmAddHardware(gobject.GObject):
device = target.get_model().get_value(target.get_active_iter(), 2) device = target.get_model().get_value(target.get_active_iter(), 2)
return node, maxnode, device return node, maxnode, device
def get_config_input(self):
target = self.window.get_widget("input-type")
label = target.get_model().get_value(target.get_active_iter(), 0)
type = target.get_model().get_value(target.get_active_iter(), 1)
bus = target.get_model().get_value(target.get_active_iter(), 2)
return label, type, bus
def get_config_network(self): def get_config_network(self):
if os.getuid() != 0: if os.getuid() != 0:
return ["user"] return ["user"]
@ -260,6 +282,7 @@ class vmmAddHardware(gobject.GObject):
if hwpage == PAGE_DISK: if hwpage == PAGE_DISK:
self.window.get_widget("summary-disk").show() self.window.get_widget("summary-disk").show()
self.window.get_widget("summary-network").hide() self.window.get_widget("summary-network").hide()
self.window.get_widget("summary-input").hide()
self.window.get_widget("summary-disk-image").set_text(self.get_config_disk_image()) self.window.get_widget("summary-disk-image").set_text(self.get_config_disk_image())
disksize = self.get_config_disk_size() disksize = self.get_config_disk_size()
if disksize != None: if disksize != None:
@ -269,6 +292,7 @@ class vmmAddHardware(gobject.GObject):
elif hwpage == PAGE_NETWORK: elif hwpage == PAGE_NETWORK:
self.window.get_widget("summary-disk").hide() self.window.get_widget("summary-disk").hide()
self.window.get_widget("summary-network").show() self.window.get_widget("summary-network").show()
self.window.get_widget("summary-input").hide()
net = self.get_config_network() net = self.get_config_network()
if net[0] == "bridge": if net[0] == "bridge":
self.window.get_widget("summary-net-type").set_text(_("Shared physical device")) self.window.get_widget("summary-net-type").set_text(_("Shared physical device"))
@ -286,6 +310,16 @@ class vmmAddHardware(gobject.GObject):
self.window.get_widget("summary-mac-address").set_text(macaddr) self.window.get_widget("summary-mac-address").set_text(macaddr)
else: else:
self.window.get_widget("summary-mac-address").set_text("-") self.window.get_widget("summary-mac-address").set_text("-")
elif hwpage == PAGE_INPUT:
self.window.get_widget("summary-disk").hide()
self.window.get_widget("summary-network").hide()
self.window.get_widget("summary-input").show()
input = self.get_config_input()
self.window.get_widget("summary-input-type").set_text(input[0])
if input[1] == "tablet":
self.window.get_widget("summary-input-mode").set_text(_("Absolute movement"))
else:
self.window.get_widget("summary-input-mode").set_text(_("Relative movement"))
def close(self, ignore1=None,ignore2=None): def close(self, ignore1=None,ignore2=None):
self.topwin.hide() self.topwin.hide()
@ -307,6 +341,8 @@ class vmmAddHardware(gobject.GObject):
self.add_network() self.add_network()
elif hw == PAGE_DISK: elif hw == PAGE_DISK:
self.add_storage() self.add_storage()
elif hw == PAGE_INPUT:
self.add_input()
if self.install_error is not None: if self.install_error is not None:
dg = vmmErrorDialog(None, 0, gtk.MESSAGE_ERROR, gtk.BUTTONS_CLOSE, dg = vmmErrorDialog(None, 0, gtk.MESSAGE_ERROR, gtk.BUTTONS_CLOSE,
@ -340,6 +376,11 @@ class vmmAddHardware(gobject.GObject):
vnic.setup(self.vm.get_connection().vmm) vnic.setup(self.vm.get_connection().vmm)
self.add_device(vnic.get_xml_config()) self.add_device(vnic.get_xml_config())
def add_input(self):
input = self.get_config_input()
xml = "<input type='%s' bus='%s'/>\n" % (input[1], input[2])
self.add_device(xml)
def add_storage(self): def add_storage(self):
node, maxnode, device = self.get_config_disk_target() node, maxnode, device = self.get_config_disk_target()
filesize = None filesize = None
@ -687,6 +728,14 @@ class vmmAddHardware(gobject.GObject):
else: else:
model.append(["xvd", 26, virtinst.VirtualDisk.DEVICE_DISK, gtk.STOCK_HARDDISK, "Virtual disk"]) model.append(["xvd", 26, virtinst.VirtualDisk.DEVICE_DISK, gtk.STOCK_HARDDISK, "Virtual disk"])
def populate_input_model(self, model):
model.clear()
model.append([_("EvTouch USB Graphics Tablet"), "tablet", "usb", True])
# XXX libvirt needs to support 'model' for input devices to distinguish
# wacom from evtouch tablets
#model.append([_("Wacom Graphics Tablet"), "tablet", "usb", True])
model.append([_("Generic USB Mouse"), "mouse", "usb", True])
def is_sparse_file(self): def is_sparse_file(self):
if self.window.get_widget("non-sparse").get_active(): if self.window.get_widget("non-sparse").get_active():
return False return False

View File

@ -45,6 +45,7 @@ HW_LIST_TYPE_CPU = 0
HW_LIST_TYPE_MEMORY = 1 HW_LIST_TYPE_MEMORY = 1
HW_LIST_TYPE_DISK = 2 HW_LIST_TYPE_DISK = 2
HW_LIST_TYPE_NIC = 3 HW_LIST_TYPE_NIC = 3
HW_LIST_TYPE_INPUT = 4
class vmmDetails(gobject.GObject): class vmmDetails(gobject.GObject):
__gsignals__ = { __gsignals__ = {
@ -126,6 +127,7 @@ class vmmDetails(gobject.GObject):
"on_config_cdrom_connect_clicked": self.toggle_cdrom, "on_config_cdrom_connect_clicked": self.toggle_cdrom,
"on_config_disk_remove_clicked": self.remove_disk, "on_config_disk_remove_clicked": self.remove_disk,
"on_config_network_remove_clicked": self.remove_network, "on_config_network_remove_clicked": self.remove_network,
"on_config_input_remove_clicked": self.remove_input,
"on_add_hardware_button_clicked": self.add_hardware, "on_add_hardware_button_clicked": self.add_hardware,
}) })
@ -201,6 +203,9 @@ class vmmDetails(gobject.GObject):
elif pagetype == HW_LIST_TYPE_NIC: elif pagetype == HW_LIST_TYPE_NIC:
self.refresh_network_page() self.refresh_network_page()
pagenum = 3 pagenum = 3
elif pagetype == HW_LIST_TYPE_INPUT:
self.refresh_input_page()
pagenum = 4
self.window.get_widget("hw-panel").set_current_page(pagenum) self.window.get_widget("hw-panel").set_current_page(pagenum)
else: else:
@ -351,6 +356,8 @@ class vmmDetails(gobject.GObject):
self.refresh_disk_page() self.refresh_disk_page()
elif pagetype == HW_LIST_TYPE_NIC: elif pagetype == HW_LIST_TYPE_NIC:
self.refresh_network_page() self.refresh_network_page()
elif pagetype == HW_LIST_TYPE_INPUT:
self.refresh_input_page()
def refresh_summary(self): def refresh_summary(self):
self.window.get_widget("overview-cpu-usage-text").set_text("%d %%" % self.vm.cpu_time_percentage()) self.window.get_widget("overview-cpu-usage-text").set_text("%d %%" % self.vm.cpu_time_percentage())
@ -439,6 +446,34 @@ class vmmDetails(gobject.GObject):
self.window.get_widget("network-source-device").set_text("-") self.window.get_widget("network-source-device").set_text("-")
self.window.get_widget("network-mac-address").set_text(netinfo[3]) self.window.get_widget("network-mac-address").set_text(netinfo[3])
def refresh_input_page(self):
vmlist = self.window.get_widget("hw-list")
selection = vmlist.get_selection()
active = selection.get_selected()
if active[1] != None:
inputinfo = active[0].get_value(active[1], HW_LIST_COL_DEVICE)
if inputinfo[3] == "tablet:usb":
self.window.get_widget("input-dev-type").set_text(_("EvTouch USB Graphics Tablet"))
elif inputinfo[3] == "mouse:usb":
self.window.get_widget("input-dev-type").set_text(_("Generic USB Mouse"))
elif inputinfo[3] == "mouse:xen":
self.window.get_widget("input-dev-type").set_text(_("Xen Mouse"))
elif inputinfo[3] == "mouse:ps2":
self.window.get_widget("input-dev-type").set_text(_("PS/2 Mouse"))
else:
self.window.get_widget("input-dev-type").set_text(inputinfo[0] + " " + inputinfo[1])
if inputinfo[0] == "tablet":
self.window.get_widget("input-dev-mode").set_text(_("Absolute Movement"))
else:
self.window.get_widget("input-dev-mode").set_text(_("Relative Movement"))
# Can't remove primary Xen or PS/2 mice
if inputinfo[0] == "mouse" and inputinfo[1] in ("xen", "ps2"):
self.window.get_widget("config-input-remove").set_sensitive(False)
else:
self.window.get_widget("config-input-remove").set_sensitive(True)
def config_vcpus_changed(self, src): def config_vcpus_changed(self, src):
self.window.get_widget("config-vcpus-apply").set_sensitive(True) self.window.get_widget("config-vcpus-apply").set_sensitive(True)
@ -505,6 +540,16 @@ class vmmDetails(gobject.GObject):
xml = vnic.get_xml_config() xml = vnic.get_xml_config()
self.vm.remove_device(xml) self.vm.remove_device(xml)
def remove_input(self, src):
vmlist = self.window.get_widget("hw-list")
selection = vmlist.get_selection()
active = selection.get_selected()
if active[1] != None:
inputinfo = active[0].get_value(active[1], HW_LIST_COL_DEVICE)
xml = "<input type='%s' bus='%s'/>" % (inputinfo[0], inputinfo[1])
self.vm.remove_device(xml)
def prepare_hw_list(self): def prepare_hw_list(self):
hw_list_model = gtk.ListStore(str, str, int, gtk.gdk.Pixbuf, int, gobject.TYPE_PYOBJECT) hw_list_model = gtk.ListStore(str, str, int, gtk.gdk.Pixbuf, int, gobject.TYPE_PYOBJECT)
@ -545,8 +590,8 @@ class vmmDetails(gobject.GObject):
# Update metadata # Update metadata
row[HW_LIST_COL_DEVICE] = disk row[HW_LIST_COL_DEVICE] = disk
missing = False missing = False
# The insert position must be *before* any NICs
if row[HW_LIST_COL_TYPE] != HW_LIST_TYPE_NIC: if row[HW_LIST_COL_TYPE] not in (HW_LIST_TYPE_NIC, HW_LIST_TYPE_INPUT):
insertAt = insertAt + 1 insertAt = insertAt + 1
# Add in row # Add in row
@ -571,14 +616,37 @@ class vmmDetails(gobject.GObject):
row[HW_LIST_COL_DEVICE] = nic row[HW_LIST_COL_DEVICE] = nic
missing = False missing = False
# Insert position is at end.... if row[HW_LIST_COL_TYPE] not in (HW_LIST_TYPE_INPUT,):
# XXX until we add support for Mice, etc insertAt = insertAt + 1
insertAt = insertAt + 1
# Add in row # Add in row
if missing: if missing:
hw_list_model.insert(insertAt, ["NIC %s" % nic[3][-9:], gtk.STOCK_NETWORK, gtk.ICON_SIZE_LARGE_TOOLBAR, None, HW_LIST_TYPE_NIC, nic]) hw_list_model.insert(insertAt, ["NIC %s" % nic[3][-9:], gtk.STOCK_NETWORK, gtk.ICON_SIZE_LARGE_TOOLBAR, None, HW_LIST_TYPE_NIC, nic])
# Populate list of input devices
currentInputs = {}
input_number = 0
for input in self.vm.get_input_devices():
missing = True
insertAt = 0
currentInputs[input[3]] = 1
for row in hw_list_model:
if row[HW_LIST_COL_TYPE] == HW_LIST_TYPE_INPUT and row[HW_LIST_COL_DEVICE][3] == input[3]:
# Update metadata
row[HW_LIST_COL_DEVICE] = input
missing = False
insertAt = insertAt + 1
# Add in row
if missing:
if input[0] == "tablet":
hw_list_model.insert(insertAt, [_("Tablet"), gtk.STOCK_INDEX, gtk.ICON_SIZE_LARGE_TOOLBAR, None, HW_LIST_TYPE_INPUT, input])
elif input[0] == "mouse":
hw_list_model.insert(insertAt, [_("Mouse"), gtk.STOCK_INDEX, gtk.ICON_SIZE_LARGE_TOOLBAR, None, HW_LIST_TYPE_INPUT, input])
else:
hw_list_model.insert(insertAt, [_("Input"), gtk.STOCK_INDEX, gtk.ICON_SIZE_LARGE_TOOLBAR, None, HW_LIST_TYPE_INPUT, input])
# Now remove any no longer current devs # Now remove any no longer current devs
devs = range(len(hw_list_model)) devs = range(len(hw_list_model))
devs.reverse() devs.reverse()
@ -591,6 +659,8 @@ class vmmDetails(gobject.GObject):
removeIt = True removeIt = True
elif row[HW_LIST_COL_TYPE] == HW_LIST_TYPE_NIC and not currentNICs.has_key(row[HW_LIST_COL_DEVICE][3]): elif row[HW_LIST_COL_TYPE] == HW_LIST_TYPE_NIC and not currentNICs.has_key(row[HW_LIST_COL_DEVICE][3]):
removeIt = True removeIt = True
elif row[HW_LIST_COL_TYPE] == HW_LIST_TYPE_INPUT and not currentInputs.has_key(row[HW_LIST_COL_DEVICE][3]):
removeIt = True
if removeIt: if removeIt:
# Re-select the first row, if we're viewing the device # Re-select the first row, if we're viewing the device

View File

@ -620,6 +620,30 @@ class vmmDomain(gobject.GObject):
doc.freeDoc() doc.freeDoc()
return nics return nics
def get_input_devices(self):
xml = self.get_xml()
doc = None
try:
doc = libxml2.parseDoc(xml)
except:
return []
ctx = doc.xpathNewContext()
inputs = []
try:
ret = ctx.xpathEval("/domain/devices/input")
for node in ret:
type = node.prop("type")
bus = node.prop("bus")
# XXX Replace 'None' with device model when libvirt supports that
inputs.append([type, bus, None, type + ":" + bus])
finally:
if ctx != None:
ctx.xpathFreeContext()
if doc != None:
doc.freeDoc()
return inputs
def add_device(self, xml): def add_device(self, xml):
logging.debug("Adding device " + xml) logging.debug("Adding device " + xml)
@ -641,7 +665,7 @@ class vmmDomain(gobject.GObject):
if device_exception: if device_exception:
raise RuntimeError, "Unable to attach device to live guest, libvirt reported error:\n" + device_exception raise RuntimeError, "Unable to attach device to live guest, libvirt reported error:\n" + device_exception
def remove_device(self, dev_xml): def remove_device(self, dev_xml):
logging.debug("Removing device " + dev_xml) logging.debug("Removing device " + dev_xml)
xml = self.get_xml() xml = self.get_xml()
@ -692,6 +716,18 @@ class vmmDomain(gobject.GObject):
newxml=doc.serialize() newxml=doc.serialize()
logging.debug("Redefine with " + newxml) logging.debug("Redefine with " + newxml)
self.get_connection().define_domain(newxml) self.get_connection().define_domain(newxml)
elif dev_type=="input":
type = dev_ctx.xpathEval("/input/@type")
bus = dev_ctx.xpathEval("/input/@bus")
if len(type) > 0 and type[0].content != None and len(bus) > 0 and bus[0].content != None:
logging.debug("Looking for type %s bus %s" % (type[0].content, bus[0].content))
ret = ctx.xpathEval("/domain/devices/input[@type='%s' and @bus='%s']" % (type[0].content, bus[0].content))
if len(ret) > 0:
ret[0].unlinkNode()
ret[0].freeNode()
newxml=doc.serialize()
logging.debug("Redefine with " + newxml)
self.get_connection().define_domain(newxml)
finally: finally:
if ctx != None: if ctx != None:

View File

@ -1620,6 +1620,304 @@
</packing> </packing>
</child> </child>
<child>
<widget class="GtkVBox" id="vbox55">
<property name="border_width">1</property>
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="spacing">0</property>
<child>
<widget class="GtkEventBox" id="page3-title">
<property name="visible">True</property>
<property name="visible_window">True</property>
<property name="above_child">False</property>
<child>
<widget class="GtkLabel" id="label392">
<property name="visible">True</property>
<property name="label" translatable="yes">&lt;span weight=&quot;heavy&quot; size=&quot;xx-large&quot; foreground=&quot;#FFF&quot;&gt;Interacting with the guest&lt;/span&gt;</property>
<property name="use_underline">False</property>
<property name="use_markup">True</property>
<property name="justify">GTK_JUSTIFY_FILL</property>
<property name="wrap">False</property>
<property name="selectable">False</property>
<property name="xalign">0</property>
<property name="yalign">0</property>
<property name="xpad">5</property>
<property name="ypad">6</property>
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
<property name="width_chars">-1</property>
<property name="single_line_mode">False</property>
<property name="angle">0</property>
</widget>
</child>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">True</property>
</packing>
</child>
<child>
<widget class="GtkVBox" id="vbox56">
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="spacing">0</property>
<child>
<widget class="GtkLabel" id="label393">
<property name="visible">True</property>
<property name="label" translatable="yes">Please indicate what kind of pointer device to connect to the guest.</property>
<property name="use_underline">False</property>
<property name="use_markup">True</property>
<property name="justify">GTK_JUSTIFY_LEFT</property>
<property name="wrap">True</property>
<property name="selectable">False</property>
<property name="xalign">0</property>
<property name="yalign">0.5</property>
<property name="xpad">20</property>
<property name="ypad">10</property>
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
<property name="width_chars">-1</property>
<property name="single_line_mode">False</property>
<property name="angle">0</property>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<child>
<widget class="GtkAlignment" id="alignment152">
<property name="visible">True</property>
<property name="xalign">0.5</property>
<property name="yalign">0.5</property>
<property name="xscale">1</property>
<property name="yscale">1</property>
<property name="top_padding">0</property>
<property name="bottom_padding">0</property>
<property name="left_padding">25</property>
<property name="right_padding">15</property>
<child>
<widget class="GtkFrame" id="frame3">
<property name="border_width">6</property>
<property name="visible">True</property>
<property name="label_xalign">0</property>
<property name="label_yalign">0.5</property>
<property name="shadow_type">GTK_SHADOW_NONE</property>
<child>
<widget class="GtkAlignment" id="alignment153">
<property name="visible">True</property>
<property name="xalign">0.5</property>
<property name="yalign">0.5</property>
<property name="xscale">1</property>
<property name="yscale">1</property>
<property name="top_padding">0</property>
<property name="bottom_padding">0</property>
<property name="left_padding">12</property>
<property name="right_padding">0</property>
<child>
<widget class="GtkTable" id="table33">
<property name="border_width">6</property>
<property name="visible">True</property>
<property name="n_rows">2</property>
<property name="n_columns">2</property>
<property name="homogeneous">False</property>
<property name="row_spacing">6</property>
<property name="column_spacing">6</property>
<child>
<widget class="GtkAlignment" id="alignment153">
<property name="visible">True</property>
<property name="xalign">0.5</property>
<property name="yalign">0.5</property>
<property name="xscale">1</property>
<property name="yscale">1</property>
<property name="top_padding">0</property>
<property name="bottom_padding">0</property>
<property name="left_padding">40</property>
<property name="right_padding">0</property>
<child>
<widget class="GtkHBox" id="hbox65">
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="spacing">0</property>
<child>
<widget class="GtkImage" id="image105">
<property name="visible">True</property>
<property name="icon_size">4</property>
<property name="icon_name">gtk-dialog-info</property>
<property name="xalign">0.5</property>
<property name="yalign">0</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">True</property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="label394">
<property name="visible">True</property>
<property name="label" translatable="yes">&lt;small&gt;&lt;b&gt;Tip:&lt;/b&gt; Adding a graphics tablet and configuring it as the default pointer in the guest OS will ensure the virtual cursor moves in sync with the local desktop cursor .&lt;/small&gt;</property>
<property name="use_underline">False</property>
<property name="use_markup">True</property>
<property name="justify">GTK_JUSTIFY_LEFT</property>
<property name="wrap">True</property>
<property name="selectable">False</property>
<property name="xalign">0.5</property>
<property name="yalign">0.5</property>
<property name="xpad">7</property>
<property name="ypad">0</property>
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
<property name="width_chars">-1</property>
<property name="single_line_mode">False</property>
<property name="angle">0</property>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
</widget>
</child>
</widget>
<packing>
<property name="left_attach">0</property>
<property name="right_attach">2</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="x_options">fill</property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="label395">
<property name="visible">True</property>
<property name="label" translatable="yes">Type:</property>
<property name="use_underline">False</property>
<property name="use_markup">False</property>
<property name="justify">GTK_JUSTIFY_LEFT</property>
<property name="wrap">False</property>
<property name="selectable">False</property>
<property name="xalign">1</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
<property name="width_chars">-1</property>
<property name="single_line_mode">False</property>
<property name="angle">0</property>
</widget>
<packing>
<property name="left_attach">0</property>
<property name="right_attach">1</property>
<property name="top_attach">0</property>
<property name="bottom_attach">1</property>
<property name="x_options">fill</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkComboBox" id="input-type">
<property name="visible">True</property>
<property name="add_tearoffs">False</property>
<property name="focus_on_click">True</property>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">0</property>
<property name="bottom_attach">1</property>
</packing>
</child>
</widget>
</child>
</widget>
</child>
<child>
<widget class="GtkLabel" id="label394">
<property name="visible">True</property>
<property name="label" translatable="yes">&lt;b&gt;Virtual pointer&lt;/b&gt;</property>
<property name="use_underline">False</property>
<property name="use_markup">True</property>
<property name="justify">GTK_JUSTIFY_LEFT</property>
<property name="wrap">False</property>
<property name="selectable">False</property>
<property name="xalign">0.5</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
<property name="width_chars">-1</property>
<property name="single_line_mode">False</property>
<property name="angle">0</property>
</widget>
<packing>
<property name="type">label_item</property>
</packing>
</child>
</widget>
</child>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">True</property>
</packing>
</child>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">True</property>
<property name="fill">True</property>
</packing>
</child>
</widget>
<packing>
<property name="tab_expand">False</property>
<property name="tab_fill">True</property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="label391">
<property name="visible">True</property>
<property name="label" translatable="yes">Input</property>
<property name="use_underline">False</property>
<property name="use_markup">False</property>
<property name="justify">GTK_JUSTIFY_LEFT</property>
<property name="wrap">False</property>
<property name="selectable">False</property>
<property name="xalign">0.5</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
<property name="width_chars">-1</property>
<property name="single_line_mode">False</property>
<property name="angle">0</property>
</widget>
<packing>
<property name="type">tab</property>
</packing>
</child>
<child> <child>
<widget class="GtkVBox" id="vbox41"> <widget class="GtkVBox" id="vbox41">
<property name="border_width">1</property> <property name="border_width">1</property>
@ -1640,7 +1938,7 @@
<property name="right_padding">0</property> <property name="right_padding">0</property>
<child> <child>
<widget class="GtkEventBox" id="page3-title"> <widget class="GtkEventBox" id="page4-title">
<property name="visible">True</property> <property name="visible">True</property>
<property name="visible_window">True</property> <property name="visible_window">True</property>
<property name="above_child">False</property> <property name="above_child">False</property>
@ -2060,6 +2358,163 @@
<property name="fill">True</property> <property name="fill">True</property>
</packing> </packing>
</child> </child>
<child>
<widget class="GtkTable" id="summary-input">
<property name="border_width">6</property>
<property name="visible">True</property>
<property name="n_rows">3</property>
<property name="n_columns">3</property>
<property name="homogeneous">False</property>
<property name="row_spacing">3</property>
<property name="column_spacing">3</property>
<child>
<widget class="GtkLabel" id="label396">
<property name="visible">True</property>
<property name="label" translatable="yes">&lt;b&gt;Pointer&lt;/b&gt;</property>
<property name="use_underline">False</property>
<property name="use_markup">True</property>
<property name="justify">GTK_JUSTIFY_LEFT</property>
<property name="wrap">False</property>
<property name="selectable">False</property>
<property name="xalign">0</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">5</property>
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
<property name="width_chars">-1</property>
<property name="single_line_mode">False</property>
<property name="angle">0</property>
</widget>
<packing>
<property name="left_attach">0</property>
<property name="right_attach">3</property>
<property name="top_attach">0</property>
<property name="bottom_attach">1</property>
<property name="x_options">fill</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="summary-input-type">
<property name="visible">True</property>
<property name="label" translatable="yes">EvTouch Tablet</property>
<property name="use_underline">False</property>
<property name="use_markup">False</property>
<property name="justify">GTK_JUSTIFY_LEFT</property>
<property name="wrap">False</property>
<property name="selectable">False</property>
<property name="xalign">0</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
<property name="width_chars">-1</property>
<property name="single_line_mode">False</property>
<property name="angle">0</property>
</widget>
<packing>
<property name="left_attach">2</property>
<property name="right_attach">3</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="x_options">fill</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="summary-input-mode">
<property name="visible">True</property>
<property name="label" translatable="yes">Absolute</property>
<property name="use_underline">False</property>
<property name="use_markup">False</property>
<property name="justify">GTK_JUSTIFY_LEFT</property>
<property name="wrap">False</property>
<property name="selectable">False</property>
<property name="xalign">0</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
<property name="width_chars">-1</property>
<property name="single_line_mode">False</property>
<property name="angle">0</property>
</widget>
<packing>
<property name="left_attach">2</property>
<property name="right_attach">3</property>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
<property name="x_options">fill</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="label399">
<property name="visible">True</property>
<property name="label" translatable="yes">Type:</property>
<property name="use_underline">False</property>
<property name="use_markup">True</property>
<property name="justify">GTK_JUSTIFY_LEFT</property>
<property name="wrap">False</property>
<property name="selectable">False</property>
<property name="xalign">1</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
<property name="width_chars">-1</property>
<property name="single_line_mode">False</property>
<property name="angle">0</property>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="x_options">fill</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="label400">
<property name="visible">True</property>
<property name="label" translatable="yes">Mode:</property>
<property name="use_underline">False</property>
<property name="use_markup">True</property>
<property name="justify">GTK_JUSTIFY_LEFT</property>
<property name="wrap">False</property>
<property name="selectable">False</property>
<property name="xalign">1</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
<property name="width_chars">-1</property>
<property name="single_line_mode">False</property>
<property name="angle">0</property>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
<property name="x_options">fill</property>
<property name="y_options"></property>
</packing>
</child>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">True</property>
<property name="fill">True</property>
</packing>
</child>
</widget> </widget>
</child> </child>
</widget> </widget>

View File

@ -2733,6 +2733,326 @@
<property name="type">tab</property> <property name="type">tab</property>
</packing> </packing>
</child> </child>
<child>
<widget class="GtkVBox" id="vbox56">
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="spacing">0</property>
<child>
<widget class="GtkFrame" id="frame11">
<property name="visible">True</property>
<property name="label_xalign">0</property>
<property name="label_yalign">0.5</property>
<property name="shadow_type">GTK_SHADOW_NONE</property>
<child>
<widget class="GtkAlignment" id="alignment150">
<property name="visible">True</property>
<property name="xalign">0.5</property>
<property name="yalign">0.5</property>
<property name="xscale">1</property>
<property name="yscale">1</property>
<property name="top_padding">5</property>
<property name="bottom_padding">3</property>
<property name="left_padding">12</property>
<property name="right_padding">0</property>
<child>
<widget class="GtkTable" id="table33">
<property name="border_width">3</property>
<property name="visible">True</property>
<property name="n_rows">2</property>
<property name="n_columns">2</property>
<property name="homogeneous">False</property>
<property name="row_spacing">3</property>
<property name="column_spacing">3</property>
<child>
<widget class="GtkLabel" id="label402">
<property name="visible">True</property>
<property name="label" translatable="yes">Type:</property>
<property name="use_underline">True</property>
<property name="use_markup">False</property>
<property name="justify">GTK_JUSTIFY_LEFT</property>
<property name="wrap">False</property>
<property name="selectable">False</property>
<property name="xalign">0</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
<property name="width_chars">-1</property>
<property name="single_line_mode">False</property>
<property name="angle">0</property>
</widget>
<packing>
<property name="left_attach">0</property>
<property name="right_attach">1</property>
<property name="top_attach">0</property>
<property name="bottom_attach">1</property>
<property name="x_options">fill</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="input-dev-type">
<property name="visible">True</property>
<property name="label" translatable="yes">label403</property>
<property name="use_underline">False</property>
<property name="use_markup">False</property>
<property name="justify">GTK_JUSTIFY_LEFT</property>
<property name="wrap">False</property>
<property name="selectable">False</property>
<property name="xalign">0</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
<property name="width_chars">-1</property>
<property name="single_line_mode">False</property>
<property name="angle">0</property>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">0</property>
<property name="bottom_attach">1</property>
<property name="x_options">fill</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="label405">
<property name="visible">True</property>
<property name="label" translatable="yes">Mode:</property>
<property name="use_underline">False</property>
<property name="use_markup">False</property>
<property name="justify">GTK_JUSTIFY_LEFT</property>
<property name="wrap">False</property>
<property name="selectable">False</property>
<property name="xalign">0</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
<property name="width_chars">-1</property>
<property name="single_line_mode">False</property>
<property name="angle">0</property>
</widget>
<packing>
<property name="left_attach">0</property>
<property name="right_attach">1</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="x_options">fill</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="input-dev-mode">
<property name="visible">True</property>
<property name="label" translatable="yes">label401</property>
<property name="use_underline">False</property>
<property name="use_markup">False</property>
<property name="justify">GTK_JUSTIFY_LEFT</property>
<property name="wrap">False</property>
<property name="selectable">False</property>
<property name="xalign">0</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
<property name="width_chars">-1</property>
<property name="single_line_mode">False</property>
<property name="angle">0</property>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="x_options">fill</property>
<property name="y_options"></property>
</packing>
</child>
</widget>
</child>
</widget>
</child>
<child>
<widget class="GtkLabel" id="label407">
<property name="visible">True</property>
<property name="label" translatable="yes">&lt;b&gt;Virtual Pointer&lt;/b&gt;</property>
<property name="use_underline">False</property>
<property name="use_markup">True</property>
<property name="justify">GTK_JUSTIFY_LEFT</property>
<property name="wrap">False</property>
<property name="selectable">False</property>
<property name="xalign">0.5</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
<property name="width_chars">-1</property>
<property name="single_line_mode">False</property>
<property name="angle">0</property>
</widget>
<packing>
<property name="type">label_item</property>
</packing>
</child>
</widget>
<packing>
<property name="padding">15</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<child>
<widget class="GtkHBox" id="hbox51">
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="spacing">0</property>
<child>
<widget class="GtkAlignment" id="alignment151">
<property name="visible">True</property>
<property name="xalign">0.5</property>
<property name="yalign">0.5</property>
<property name="xscale">1</property>
<property name="yscale">1</property>
<property name="top_padding">0</property>
<property name="bottom_padding">0</property>
<property name="left_padding">13</property>
<property name="right_padding">0</property>
<child>
<widget class="GtkImage" id="image77">
<property name="visible">True</property>
<property name="stock">gtk-info</property>
<property name="icon_size">4</property>
<property name="xalign">0.5</property>
<property name="yalign">0</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
</widget>
</child>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<child>
<widget class="GtkAlignment" id="alignment152">
<property name="visible">True</property>
<property name="xalign">0.5</property>
<property name="yalign">0.5</property>
<property name="xscale">1</property>
<property name="yscale">1</property>
<property name="top_padding">0</property>
<property name="bottom_padding">0</property>
<property name="left_padding">3</property>
<property name="right_padding">0</property>
<child>
<widget class="GtkLabel" id="label408">
<property name="visible">True</property>
<property name="label" translatable="yes">&lt;b&gt;Tip:&lt;/b&gt; A graphics tablet configured as the default pointer in the guest OS will ensure that the virtual cursor moves in sync with the local desktop cursor.</property>
<property name="use_underline">False</property>
<property name="use_markup">True</property>
<property name="justify">GTK_JUSTIFY_LEFT</property>
<property name="wrap">True</property>
<property name="selectable">False</property>
<property name="xalign">0.5</property>
<property name="yalign">0</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
<property name="width_chars">-1</property>
<property name="single_line_mode">False</property>
<property name="angle">0</property>
</widget>
</child>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">True</property>
<property name="fill">True</property>
</packing>
</child>
<child>
<widget class="GtkHButtonBox" id="hbuttonbox12">
<property name="border_width">6</property>
<property name="visible">True</property>
<property name="layout_style">GTK_BUTTONBOX_END</property>
<property name="spacing">0</property>
<child>
<widget class="GtkButton" id="config-input-remove">
<property name="visible">True</property>
<property name="can_default">True</property>
<property name="can_focus">True</property>
<property name="label">gtk-remove</property>
<property name="use_stock">True</property>
<property name="relief">GTK_RELIEF_NORMAL</property>
<property name="focus_on_click">True</property>
<signal name="clicked" handler="on_config_input_remove_clicked" last_modification_time="Tue, 25 Sep 2007 23:57:19 GMT"/>
</widget>
</child>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
</widget>
<packing>
<property name="tab_expand">False</property>
<property name="tab_fill">True</property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="label401">
<property name="visible">True</property>
<property name="label" translatable="yes">Input</property>
<property name="use_underline">False</property>
<property name="use_markup">False</property>
<property name="justify">GTK_JUSTIFY_LEFT</property>
<property name="wrap">False</property>
<property name="selectable">False</property>
<property name="xalign">0.5</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
<property name="width_chars">-1</property>
<property name="single_line_mode">False</property>
<property name="angle">0</property>
</widget>
<packing>
<property name="type">tab</property>
</packing>
</child>
</widget> </widget>
<packing> <packing>
<property name="shrink">True</property> <property name="shrink">True</property>