Ticket #2006: touchpad.py

File touchpad.py, 4.8 KB (added by walter, 14 years ago)

final version of the patch

Line 
1# Copyright (C) 2010, Walter Bender, Sugar Labs
2#
3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by
5# the Free Software Foundation; either version 2 of the License, or
6# (at your option) any later version.
7#
8# This program is distributed in the hope that it will be useful,
9# but WITHOUT ANY WARRANTY; without even the implied warranty of
10# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11# GNU General Public License for more details.
12#
13# You should have received a copy of the GNU General Public License
14# along with this program; if not, write to the Free Software
15# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
16
17
18from gettext import gettext as _
19import os
20
21import gtk
22import gconf
23
24from sugar.graphics.tray import TrayIcon
25from sugar.graphics.xocolor import XoColor
26from sugar.graphics.palette import Palette
27from sugar.graphics import style
28
29from jarabe.frame.frameinvoker import FrameWidgetInvoker
30
31TOUCHPAD_MODES = ['capacitive', 'resistive']
32STATUS_TEXT = {TOUCHPAD_MODES[0]: _('finger'), TOUCHPAD_MODES[1]: _('stylus')}
33STATUS_ICON = {TOUCHPAD_MODES[0]: 'touchpad-' + TOUCHPAD_MODES[0],
34               TOUCHPAD_MODES[1]: 'touchpad-' + TOUCHPAD_MODES[1]}
35# FLAG_FILE is used to preserve status between boots.
36FLAG_FILE = '.olpc-pentablet-mode'
37# NODE_PATH is used to communicate with the touchpad device.
38NODE_PATH = '/sys/devices/platform/i8042/serio1/ptmode'
39
40class DeviceView(TrayIcon):
41    """ Manage the touchpad mode from the device palette on the Frame. """
42
43    FRAME_POSITION_RELATIVE = 500
44
45    def __init__(self):
46        """ Create the touchpad palette and display it on Frame. """
47        icon_name = STATUS_ICON[read_touchpad_mode()]
48
49        client = gconf.client_get_default()
50        color = XoColor(client.get_string('/desktop/sugar/user/color'))
51        TrayIcon.__init__(self, icon_name=icon_name, xo_color=color)
52
53        self.set_palette_invoker(FrameWidgetInvoker(self))
54        self.connect('button-release-event', self.__button_release_event_cb)
55
56    def create_palette(self):
57        """ On create, set the current mode. """
58        self.palette = ResourcePalette(_('My touchpad'), self.icon)
59        self.palette.set_group_id('frame')
60        return self.palette
61
62    def __button_release_event_cb(self, widget, event):
63        """ On button release, switch modes. """
64        self.palette.toggle_mode()
65        return True
66
67
68class ResourcePalette(Palette):
69    """ Query the current state of the touchpad and update the display. """
70
71    def __init__(self, primary_text, icon):
72        """ Create the palette and initilize with current touchpad status. """
73        Palette.__init__(self, label=primary_text)
74
75        self._icon = icon
76
77        vbox = gtk.VBox()
78        self.set_content(vbox)
79
80        self._status_text = gtk.Label()
81        vbox.pack_start(self._status_text, padding=style.DEFAULT_PADDING)
82        self._status_text.show()
83
84        vbox.show()
85
86        self._mode = read_touchpad_mode()
87        self._update()
88
89    def _update(self):
90        """ Update the label and icon based on the current mode. """
91        self._status_text.set_label(STATUS_TEXT[self._mode])
92        self._icon.props.icon_name = STATUS_ICON[self._mode]
93
94    def toggle_mode(self):
95        """ On mouse click, toggle the mode. """
96        self._mode = TOUCHPAD_MODES[1 - TOUCHPAD_MODES.index(self._mode)]
97        write_touchpad_mode(self._mode)
98        self._update()
99
100
101def setup(tray):
102    """ Touchpad palette only appears when the device exisits. """
103    if os.path.exists(NODE_PATH):
104        tray.add_device(DeviceView())
105
106        # if _flag_path exists, set the initial device value to stylus
107        _flag_path = os.join(os.environ['HOME'], FLAG_FILE)
108        if os.path.exists(_flag_path):
109            write_to_node_file(str(TOUCHPAD_MODES.index('stylus')))
110
111
112def read_touchpad_mode():
113    """ Read the touchpad mode from the node path. """
114    node_file_handle = open(NODE_PATH, 'r')
115    text = node_file_handle.read()
116    node_file_handle.close()
117
118    return TOUCHPAD_MODES[int(text[0])]
119
120
121def write_touchpad_mode(touchpad):
122    """ Write the touchpad mode to the node path and set/unset the flag. """
123    touchpad_mode_index = TOUCHPAD_MODES.index(touchpad)
124
125    write_to_node_file(str(touchpad_mode_index))
126
127    _flag_path = os.join(os.environ['HOME'], FLAG_FILE)
128    if touchpad_mode_index == 0:
129        if os.path.exists(_flag_path):
130            os.remove(FLAG_PATH)
131    else:
132        flag_file_handle = open(_flag_path, 'w')
133        flag_file_handle.close()
134
135
136def write_to_node_file(value):
137    """ Write to node path, catching exception is there is a problem """
138    try:
139        node_file_handle = open(NODE_PATH, 'w')
140    except IOError, e:
141        print e
142        return
143    node_file_handle.write(value)
144    node_file_handle.close()