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 | |
---|
18 | from gettext import gettext as _ |
---|
19 | import os |
---|
20 | |
---|
21 | import gtk |
---|
22 | import gconf |
---|
23 | |
---|
24 | from sugar.graphics.tray import TrayIcon |
---|
25 | from sugar.graphics.xocolor import XoColor |
---|
26 | from sugar.graphics.palette import Palette |
---|
27 | from sugar.graphics import style |
---|
28 | |
---|
29 | from jarabe.frame.frameinvoker import FrameWidgetInvoker |
---|
30 | |
---|
31 | TOUCHPAD_MODES = ['capacitive', 'resistive'] |
---|
32 | STATUS_TEXT = {TOUCHPAD_MODES[0]: _('finger'), TOUCHPAD_MODES[1]: _('stylus')} |
---|
33 | STATUS_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. |
---|
36 | FLAG_FILE = '.olpc-pentablet-mode' |
---|
37 | # NODE_PATH is used to communicate with the touchpad device. |
---|
38 | NODE_PATH = '/sys/devices/platform/i8042/serio1/ptmode' |
---|
39 | |
---|
40 | class 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 | |
---|
68 | class 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 | |
---|
101 | def 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 | |
---|
112 | def 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 | |
---|
121 | def 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 | |
---|
136 | def 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() |
---|