Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/extensions/deviceicon/touchpad.py
diff options
context:
space:
mode:
Diffstat (limited to 'extensions/deviceicon/touchpad.py')
-rw-r--r--extensions/deviceicon/touchpad.py146
1 files changed, 146 insertions, 0 deletions
diff --git a/extensions/deviceicon/touchpad.py b/extensions/deviceicon/touchpad.py
new file mode 100644
index 0000000..150e8dc
--- /dev/null
+++ b/extensions/deviceicon/touchpad.py
@@ -0,0 +1,146 @@
+# Copyright (C) 2010, Walter Bender, Sugar Labs
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+
+from gettext import gettext as _
+import os
+
+import gtk
+import gconf
+import glib
+
+import logging
+
+from sugar.graphics.tray import TrayIcon
+from sugar.graphics.xocolor import XoColor
+from sugar.graphics.palette import Palette
+from sugar.graphics import style
+
+from jarabe.frame.frameinvoker import FrameWidgetInvoker
+
+TOUCHPAD_MODE_MOUSE = 'mouse'
+TOUCHPAD_MODE_PENTABLET = 'pentablet'
+
+TOUCHPAD_MODES = (TOUCHPAD_MODE_MOUSE, TOUCHPAD_MODE_PENTABLET)
+STATUS_TEXT = (_('finger'), _('stylus'))
+STATUS_ICON = ('touchpad-capacitive', 'touchpad-resistive')
+
+# NODE_PATH is used to communicate with the touchpad device.
+NODE_PATH = '/sys/devices/platform/i8042/serio1/hgpk_mode'
+
+
+class DeviceView(TrayIcon):
+ """ Manage the touchpad mode from the device palette on the Frame. """
+
+ FRAME_POSITION_RELATIVE = 500
+
+ def __init__(self):
+ """ Create the icon that represents the touchpad. """
+ icon_name = STATUS_ICON[_read_touchpad_mode()]
+
+ client = gconf.client_get_default()
+ color = XoColor(client.get_string('/desktop/sugar/user/color'))
+ TrayIcon.__init__(self, icon_name=icon_name, xo_color=color)
+
+ self.set_palette_invoker(FrameWidgetInvoker(self))
+ self.connect('button-release-event', self.__button_release_event_cb)
+
+ def create_palette(self):
+ """ Create a palette for this icon; called by the Sugar framework
+ when a palette needs to be displayed. """
+ label = glib.markup_escape_text(_('My touchpad'))
+ self.palette = ResourcePalette(label, self.icon)
+ self.palette.set_group_id('frame')
+ return self.palette
+
+ def __button_release_event_cb(self, widget, event):
+ """ Callback for button release event; used to invoke touchpad-mode
+ change. """
+ self.palette.toggle_mode()
+ return True
+
+
+class ResourcePalette(Palette):
+ """ Palette attached to the decive icon that represents the touchpas. """
+
+ def __init__(self, primary_text, icon):
+ """ Create the palette and initilize with current touchpad status. """
+ Palette.__init__(self, label=primary_text)
+
+ self._icon = icon
+
+ vbox = gtk.VBox()
+ self.set_content(vbox)
+
+ self._status_text = gtk.Label()
+ vbox.pack_start(self._status_text, padding=style.DEFAULT_PADDING)
+ self._status_text.show()
+
+ vbox.show()
+
+ self._mode = _read_touchpad_mode()
+ self._update()
+
+ def _update(self):
+ """ Update the label and icon based on the current mode. """
+ self._status_text.set_label(STATUS_TEXT[self._mode])
+ self._icon.props.icon_name = STATUS_ICON[self._mode]
+
+ def toggle_mode(self):
+ """ Toggle the touchpad mode. """
+ self._mode = 1 - self._mode
+ _write_touchpad_mode(self._mode)
+ self._update()
+
+
+def setup(tray):
+ """ Initialize the devic icon; called by the shell when initializing the
+ Frame. """
+ if os.path.exists(NODE_PATH):
+ tray.add_device(DeviceView())
+ _write_touchpad_mode_str(TOUCHPAD_MODE_MOUSE)
+
+
+def _read_touchpad_mode_str():
+ """ Read the touchpad mode string from the node path. """
+ node_file_handle = open(NODE_PATH, 'r')
+ text = node_file_handle.read().strip().lower()
+ node_file_handle.close()
+ return text
+
+
+def _read_touchpad_mode():
+ """ Read the touchpad mode and return the mode index. """
+ mode_str = _read_touchpad_mode_str()
+ if mode_str not in TOUCHPAD_MODES:
+ return None
+ return TOUCHPAD_MODES.index(mode_str)
+
+
+def _write_touchpad_mode_str(mode_str):
+ """ Write the touchpad mode to the node path. """
+ try:
+ node_file_handle = open(NODE_PATH, 'w')
+ except IOError, e:
+ logging.error('Error opening %s for writing: %s', NODE_PATH, e)
+ return
+ node_file_handle.write(mode_str)
+ node_file_handle.close()
+
+
+def _write_touchpad_mode(mode_num):
+ """ Look up the mode (by index) and write to node path. """
+ return _write_touchpad_mode_str(TOUCHPAD_MODES[mode_num])