From: Michael Mrozek Date: Sat, 11 Jun 2011 07:17:00 +0000 (+0200) Subject: pandora-scripts: Added new version of op_nubmode and added that to sudoers X-Git-Tag: sz_beta3~148 X-Git-Url: https://git.openpandora.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f6fe775bb6cf8bd1c20b8938ef2f523c5f34ebc4;p=openpandora.oe.git pandora-scripts: Added new version of op_nubmode and added that to sudoers --- diff --git a/recipes/pandora-system/pandora-scripts.bb b/recipes/pandora-system/pandora-scripts.bb index b16b4b1..a80a15d 100644 --- a/recipes/pandora-system/pandora-scripts.bb +++ b/recipes/pandora-system/pandora-scripts.bb @@ -6,7 +6,7 @@ COMPATIBLE_MACHINE = "omap3-pandora" DEPENDS = "zenity dbus" RDEPENDS = "zenity dbus" -PR = "r62" +PR = "r64" SRC_URI = " \ file://op_bright.sh \ @@ -50,6 +50,7 @@ SRC_URI = " \ file://service.conf \ file://nub_profiles.conf \ file://nubmode.glade \ + file://reset_nubs.sh \ file://pndlogo.png \ file://default_up \ file://none_up \ @@ -94,7 +95,9 @@ do_install() { install -m 0755 ${WORKDIR}/op_battlow.sh ${D}${prefix}/pandora/scripts/ install -m 0755 ${WORKDIR}/op_bright_up.sh ${D}${prefix}/pandora/scripts/ install -m 0755 ${WORKDIR}/op_menu.sh ${D}${prefix}/pandora/scripts/ + install -m 0755 ${WORKDIR}/reset_nubs.sh ${D}${prefix}/pandora/scripts/ install -m 0644 ${WORKDIR}/pndlogo.png ${D}${prefix}/pandora/scripts/ + install -m 0644 ${WORKDIR}/nubmode.glade ${D}${prefix}/pandora/scripts/ diff --git a/recipes/pandora-system/pandora-scripts/nubmode.glade b/recipes/pandora-system/pandora-scripts/nubmode.glade index a77be2b..8bbd937 100755 --- a/recipes/pandora-system/pandora-scripts/nubmode.glade +++ b/recipes/pandora-system/pandora-scripts/nubmode.glade @@ -5,6 +5,7 @@ Nub configuration center + True @@ -24,7 +25,7 @@ True - + mouse movement True True @@ -37,42 +38,42 @@ - + mouse buttons True True False True True - LeftRadio_mouse + Rmouse0 1 - + scrolling True True False True True - LeftRadio_mouse + Rmouse0 2 - + joystick True True False True True - LeftRadio_mouse + Rmouse0 3 @@ -104,7 +105,7 @@ True - + mouse movement True True @@ -117,42 +118,42 @@ - + mouse buttons True True False True True - RightRadio_mouse + Rmouse1 1 - + scrolling True True False True True - RightRadio_mouse + Rmouse1 2 - + joystick True True False True True - RightRadio_mouse + Rmouse1 3 @@ -179,7 +180,7 @@ True True - lbutton + button0 0 @@ -191,7 +192,7 @@ True True - lmouse + mouse0 0 @@ -274,7 +275,7 @@ True True - lscroll + rate0 0 @@ -286,7 +287,7 @@ True True - lscrollx + scrollx0 0 @@ -298,7 +299,7 @@ True True - lscrolly + scrolly0 0 @@ -310,7 +311,7 @@ True True - rmouse + mouse1 0 @@ -324,7 +325,7 @@ True True - rbutton + button1 0 @@ -338,7 +339,7 @@ True True - rscroll + rate1 0 @@ -352,7 +353,7 @@ True True - rscrollx + scrollx1 0 @@ -367,7 +368,7 @@ True True delayed - rscrolly + scrolly1 0 @@ -389,77 +390,33 @@ - - Reset left nub + True - True - True - - 8 - 9 + 1 + 2 + 9 + 10 2 - - Reset right nub + True - True - True - + 2 - 2 3 - 8 - 9 - 2 - - - - - Scan nub state - True - True - True - top - - - - 1 - 2 - 8 - 9 - 2 + 10 + 11 - + + 84 True - - - 84 - True - pndlogo.png - - - 0 - - - - - Apply configuration - True - True - True - - - - 1 - - + pndlogo.png 1 @@ -475,117 +432,141 @@ + 2 + 3 9 10 2 - + + Delete profile True + True + True + - 1 - 2 9 10 2 - - Load profile + + Write nub settings True True True - + 2 3 - 9 - 10 + 8 + 9 2 - + + Read nub settings True - 2 + True + True + top + - 3 - 10 - 11 + 1 + 2 + 8 + 9 + 2 + + + + + Reset nubs... + True + True + True + + + + 8 + 9 + 2 - + 150 50 300 1 10 - + 150 50 300 1 10 - + 20 1 40 1 10 - + 20 1 40 1 10 - + 20 1 40 1 10 - + 20 1 40 1 10 - + 7 -32 32 1 10 - + 7 -32 32 1 10 - + 7 -32 32 1 10 - + 7 -32 32 diff --git a/recipes/pandora-system/pandora-scripts/op_nubmode.py b/recipes/pandora-system/pandora-scripts/op_nubmode.py index f20dfda..7b858ff 100755 --- a/recipes/pandora-system/pandora-scripts/op_nubmode.py +++ b/recipes/pandora-system/pandora-scripts/op_nubmode.py @@ -1,11 +1,5 @@ #!/usr/bin/python -# TODO: -# - fix nub reset (permission issue) and add test -# - wrap into PND -# - upload into beta software, gather & process feedback -# - upload into repo - import os import re import sys @@ -13,88 +7,164 @@ import gtk import time import optparse -# EDs reset in op_nubmode.sh -# -# @left-nub: 3-0066/reset - -# echo 1 > /sys/bus/i2c/drivers/vsense/3-0067/reset -# sleep 1 -# echo 0 > /sys/bus/i2c/drivers/vsense/3-0067/reset -# curmode=$(cat /proc/pandora/nub1/mode) -# echo mouse > /proc/pandora/nub1/mode -# while ! zenity --question --title="Resetted right nub" --text="The right nub has been resetted.\nPlease try to move the mouse cursor\nto test if it is working properly." --ok-label="Working properly" --cancel-label="Reset again"; do -# echo 1 > /sys/bus/i2c/drivers/vsense/3-0067/reset -# sleep 1 -# echo 0 > /sys/bus/i2c/drivers/vsense/3-0067/reset -# done -# echo $curmode > /proc/pandora/nub1/mode - # ================================================================ GUI_DESCRIPTION = 'nubmode.glade' PROFILES = '/etc/pandora/conf/nub_profiles.conf' +# Shell command to reset nub: 3-0066 = left-nub, 3-0067 = right-nub +# apparently they are linked and resetting one resets both. +#RESET_CMD = 'echo %i > /sys/bus/i2c/drivers/vsense/3-00%i/reset' +RESET_CMD = "sudo ./reset_nubs.sh" + +# Valid values for mode setting MODES = ("mouse", "mbuttons", "scroll", "absolute") -SLIDERS = ("mouse", "button", "scroll", "scrollx", "scrolly") +# Paths for reading and writing different configuration options %i -> 0 | 1 +SETTINGS = dict( + mode='/proc/pandora/nub%s/mode', + mouse='/proc/pandora/nub%s/mouse_sensitivity', + button='/proc/pandora/nub%s/mbutton_threshold', + rate='/proc/pandora/nub%s/scroll_rate', + scrollx='/proc/pandora/nub%s/scrollx_sensitivity', + scrolly='/proc/pandora/nub%s/scrolly_sensitivity', +) + +# format for saving/loading +FILE_ORDER = ("mode", "mouse", "button", "rate", "scrollx", "scrolly") + +# Default configuration DEFAULT_PROFILENAME = "Default" -DEFAULT_PROFILE = [DEFAULT_PROFILENAME, - "mouse 150 20 20 7 7", "mbuttons 150 20 20 7 7"] +DEFAULT_DICT = dict(mode0='mouse', mode1='mbuttons', mouse0='150', mouse1='150', + button0='20', button1='20', rate0='20', rate1='20', + scrollx0='7', scrollx1='7', scrolly0='7', scrolly1='7') + +# Types of model changes for view updates +(MODEL_PROFILE_CHANGE, MODEL_VALUE_CHANGE) = range(2) + +# Documentation for commandline options +HELP_RESET = "Reset specified nub(s). Format: left,right" +HELP_LEFT_NUB = ("Configure left nub. Include -a flag to activate. Format: %s. E.g. %s" % + (' '.join(FILE_ORDER), + ' '.join(DEFAULT_DICT[k+'0'] for k in FILE_ORDER))) +HELP_RIGHT_NUB = ("Configure right nub. Include -a flag to activate. Format: %s. E.g. %s" % + (' '.join(FILE_ORDER), + ' '.join(DEFAULT_DICT[k+'1'] for k in FILE_ORDER))) +HELP_SAVE = "Store current configuration as specified profile (no spaces allowed)" +HELP_APPLY = "Write currently loaded configuration to nubs." +HELP_LOAD = "Load and apply specified nub configuration profile" +HELP_DEL = "Delete specified nub configuration profile" + +# Commandline input type checking +TYPECHECK = dict(mode='(%s)' % '|'.join(MODES), + mouse='(\d+)', button='(\d+)', + rate='(\d+)', scrollx='(\d+)', scrolly='(\d+)') +RE_FORMAT = ','.join(TYPECHECK[k] for k in FILE_ORDER) +BOUNDS = dict(mouse=(50, 300), button=(1, 40), rate=(1, 40), + scrollx=(-32,32), scrolly=(-32,32)) -RESET_CMD_LEFT = 'echo %i > /sys/bus/i2c/drivers/vsense/3-0066/reset' -RESET_CMD_RIGHT = 'echo %i > /sys/bus/i2c/drivers/vsense/3-0067/reset' +# ================================================================ +# There is a bug in setting scrollx/scrolly sensitivity in the +# firmware (to be fixed in hotfix 6). +# Detect and set FIX_SCROLLXY_BUG to use a workaround. -# Settings read/written to /proc/pandora/nub (: 0 or 1) -FILES = "mode mouse_sensitivity mbutton_threshold scroll_rate scrollx_sensitivity scrolly_sensitivity".split(' ') -LEFT_NUB_CONFIG = [os.path.join('/proc/pandora/nub0', x) for x in FILES] -RIGHT_NUB_CONFIG = [os.path.join('/proc/pandora/nub1', x) for x in FILES] +def ReadWriteTest(value=None): + with open(SETTINGS['scrollx'] % 0, 'w' if value else 'r') as f: + return f.write('%s\n' % value) if value else f.readline().rstrip() -RE_FORMAT = "(%s),(\d+),(\d+),(\d+),(\d+),(\d+)" % '|'.join(MODES) -BOUNDS = ((50, 300), (1, 40), (1, 40), (-32, 32), (-32, 32)) +tmp = int(ReadWriteTest()) # backup original +ReadWriteTest(tmp + (-1 if tmp < 0 else 1)) # write corrected value +FIX_SCROLLXY_BUG = int(ReadWriteTest()) == tmp # fix bug if equal to original +ReadWriteTest(tmp + ((-1 if tmp < 0 else 1) if FIX_SCROLLXY_BUG else 0)) # restore # ================================================================ -def Validate(value): - mo = re.match(RE_FORMAT, value) - if mo and all(lower <= int(value) <= upper for (value, (lower, upper)) in - zip(mo.groups()[1:], BOUNDS)): - return True, list(mo.groups()) - else: - return False, None - -def ReadConfigFromProc(paths): - config = [] - for filepath in paths: - with open(filepath) as f: - config.append(f.readline().strip()) +def ReadProc(): + config = {} + for key, value in SETTINGS.iteritems(): + for c in '01': + with open(value % c, 'r') as f: + config[key+c] = f.readline().strip() return config -def StoreConfigToProc(paths, values): - # fix for scrollx, scrolly being stored one closer to zero than specified - values[-2:] = [int(v) + (-1 if v < 0 else 1) for v in values[-2:]] - - for filepath, value in zip(paths, values): - with open(filepath, 'w') as f: - f.write('%s\n' % value) +def StoreProc(dictionary): + # fix for value decrement/increment after written + if FIX_SCROLLXY_BUG: + dictionary = dictionary.copy() + for key in ('scrollx0', 'scrolly0', 'scrollx1', 'scrolly1'): + value = int(dictionary[key]) + value += -1 if value < 0 else 1 + dictionary[key] = str(value) + for key, value in SETTINGS.iteritems(): + for c in '01': + with open(value % c, 'w') as f: + f.write('%s\n' % dictionary[key+c]) + +def ProfileToString(dictionary): + return ' '.join(dictionary[k+c] for c in '01' for k in FILE_ORDER) + +def StringToProfile(line): + return dict(zip((k+c for c in '01' for k in FILE_ORDER), line.split(' '))) +def Validate(value): + mo = re.match(RE_FORMAT, value) + if mo: # verify bounds + values = dict(zip(FILE_ORDER, mo.groups())) + if all(BOUNDS[k][0] <= int(values[k]) <= BOUNDS[k][1] for k in BOUNDS): + return values + return {} -class Nub(object): - def __init__(self, builder, modeprefix, sliderprefix): - self.radios = [builder.get_object(modeprefix % m) for m in MODES] - self.sliders = [builder.get_object(sliderprefix % s) for s in SLIDERS] +# ================================================================ - def SetConfig(self, config): - i = MODES.index(config[0]) - self.radios[i].set_active(True) - for s, v in zip(self.sliders, config[1:]): - s.value = int(v) +class NubModel(object): + def __init__(self, view=None): + self.views = [view] if view else [] + self.settings = ReadProc() + self.profiles = {} + with open(PROFILES) as f: + name = None + for line in f: + if name is None: + name = line.rstrip() + else: + self.profiles[name] = StringToProfile(line.rstrip()) + name = None + + def notify(self, reason, *args): + for v in self.views: + v.update_view(reason, *args) + + def set_profile(self, name, dictionary): + notify = name not in self.profiles + self.profiles.setdefault(name, {}).update(dictionary) + if notify: + self.notify(MODEL_PROFILE_CHANGE, name, self.profiles) + + def delete_profile(self, name): + notify = name in self.profiles + del self.profiles[name] + if notify: + self.notify(MODEL_PROFILE_CHANGE, '', self.profiles) + + def load_profile(self, settings): + self.settings.update(settings) + self.notify(MODEL_VALUE_CHANGE, self.settings) + + def load_named_profile(self, name): + notify = True + if name == DEFAULT_PROFILENAME: + self.settings.update(DEFAULT_DICT) + elif name in self.profiles: + self.settings.update(self.profiles[name]) + else: + notify = False + if notify: + self.notify(MODEL_VALUE_CHANGE, self.settings) - def GetConfig(self): - i = (j for j, r in enumerate(self.radios) if r.get_active()).next() - config = [MODES[i]] - for s in self.sliders: - config.append(str(int(s.value))) - return config + def store_profiles(self, filename): + with open(filename, 'w') as f: + for name in sorted(self.profiles.keys()): + f.write('%s\n%s\n' % (name, ProfileToString(self.profiles[name]))) class NubConfig(object): @@ -105,151 +175,191 @@ class NubConfig(object): os.path.join(os.path.dirname(__file__), GUI_DESCRIPTION)) builder.connect_signals(self) - self.leftnub = Nub(builder, "LeftRadio_%s", "l%s") - self.rightnub = Nub(builder, "RightRadio_%s", "r%s") + # slider widgets, more specifically: their Adjustment objects + self.widgets = {} + for s in DEFAULT_DICT: + w = builder.get_object(s) + if w is not None: + w.connect('value-changed', self.on_slider_changed, s) + self.widgets[s] = w + + # radio buttons + for c in '01': + group = [] + for m in MODES: + w = builder.get_object('R%s%s' % (m,c)) + w.connect('clicked', self.on_radio_changed, 'mode'+c, m) + group.append(w) + self.widgets['mode'+c] = group + + self.statusbar = builder.get_object('statusbar') + self.contextid = self.statusbar.get_context_id('') - self.profiles = gtk.ListStore(str, str, str) - self.profiles.append(DEFAULT_PROFILE) - with open(PROFILES) as f: - c = map(str.rstrip, f.readlines()) - for p in zip(*(c[i::3] for i in range(3))): - self.profiles.append(p) + self.model = NubModel(self) - self.statusbar = builder.get_object("statusbar") - self.contextid = self.statusbar.get_context_id('') + self.profiles = gtk.ListStore(str) + self.profiles.append([DEFAULT_PROFILENAME]) + for name in self.model.profiles: + self.profiles.append([name]) - self.comboentry = builder.get_object("ProfileComboEntry") + self.comboentry = builder.get_object('ProfileComboEntry') self.comboentry.set_model(self.profiles) self.comboentry.set_text_column(0) + self.comboentry.connect('changed', self.on_combo_changed) self.entry = self.comboentry.get_child() - self.entry.connect('changed', self.on_combo_changed) + self.entry.connect('activate', self.on_LoadProfile_clicked) - self.load = builder.get_object('LoadProfile') + # we need a reference to change their sensitive + # setting according to the profile + self.delete = builder.get_object('DeleteProfile') self.save = builder.get_object('SaveProfile') + # this also changes sensitive of self.save & self.load self.comboentry.set_active(0) - # read current config: - self.on_UndoChanges_clicked(None) + # read current config + self.model.load_profile(ReadProc()) self.window = builder.get_object("window") - self.window.connect("destroy", self.on_window_destroy) self.window.show_all() accelgrp = gtk.AccelGroup() key, mod = gtk.accelerator_parse('Q') accelgrp.connect_group(key, mod, 0, self.on_window_destroy) - self.window.add_accel_group(accelgrp) - - def write_profiles_to_file(self): - with open(PROFILES, 'w') as f: - for name,left,right in self.profiles: - if name != DEFAULT_PROFILENAME: - f.write("%s\n%s\n%s\n" % (name, left, right)) + self.window.add_accel_group(accelgrp) + + def _update_profile_list(self, new, profiles): + self.profiles.clear() + self.profiles.append([DEFAULT_PROFILENAME]) + activate = 0 + for i, key in enumerate(sorted(profiles.keys())): + self.profiles.append([key]) + if key == new: + activate = i + self.comboentry.set_active(activate) + + def _update_widgets(self, settings): + for key, value in settings.iteritems(): + if 'mode' in key: + for w, m in zip(self.widgets[key], MODES): + w.set_active(m == value) + else: + self.widgets[key].value = int(value) + + def update_view(self, reason, *data): + if reason == MODEL_PROFILE_CHANGE: + self._update_profile_list(*data) + elif reason == MODEL_VALUE_CHANGE: + self._update_widgets(*data) + + def _lose_active(self): + # Forces the comboboxentry to lose its active selection + # such that it also generates a changed signal when we + # select the same value. + temp = self.entry.get_text() + self.entry.set_text('') + self.entry.set_text(temp) def Notify(self, message): self.statusbar.pop(self.contextid) self.statusbar.push(self.contextid, message) + def on_slider_changed(self, widget, key): + self.model.settings[key] = str(int(widget.value)) + + def on_radio_changed(self, widget, key, mode): + self.model.settings[key] = mode + def on_combo_changed(self, widget, *data): - profileid = self.comboentry.get_active() - self.load.set_sensitive(profileid != -1) - self.save.set_sensitive(profileid != 0 and self.entry.get_text() != '') - - def on_ResetLeft_clicked(self, widget, *data): - self.Notify("Resetting left nub...") - os.system(RESET_CMD_LEFT % 1) - time.sleep(1) - os.system(RESET_CMD_LEFT % 0) - self.Notify("Left nub reset") - - def on_ResetRight_clicked(self, widget, *data): - self.Notify("Resetting right nub...") - os.system(RESET_CMD_RIGHT % 1) - time.sleep(1) - os.system(RESET_CMD_RIGHT % 0) - self.Notify("Right nub reset") - - def on_UndoChanges_clicked(self, widget, *data): - self.leftnub.SetConfig(ReadConfigFromProc(LEFT_NUB_CONFIG)) - self.rightnub.SetConfig(ReadConfigFromProc(RIGHT_NUB_CONFIG)) + name = self.entry.get_text() + self.delete.set_sensitive(name in self.model.profiles) + self.save.set_sensitive(name != '' and name != DEFAULT_PROFILENAME) + if self.comboentry.get_active() != -1: + self.on_LoadProfile_clicked(None) + + def on_ResetNubs_clicked(self, widget, *data): + self.Notify("Resetting the nubs...") + os.system(RESET_CMD) + self.Notify("Nubs reset.") + + def on_ReadNubConfig_clicked(self, widget, *data): + self.model.load_profile(ReadProc()) self.Notify("Active nub configuration loaded.") - def on_ApplyChanges_clicked(self, widget, *data): - StoreConfigToProc(LEFT_NUB_CONFIG, self.leftnub.GetConfig()) - StoreConfigToProc(RIGHT_NUB_CONFIG, self.rightnub.GetConfig()) + def on_WriteNubConfig_clicked(self, widget, *data): + StoreProc(self.model.settings) self.Notify("Nub configuration updated.") def on_SaveProfile_clicked(self, widget, *data): - name = self.entry.get_text().replace(' ', '_') + name = self.entry.get_text() if name == '' or name == DEFAULT_PROFILENAME: self.Notify("Invalid profile name") else: - left = ' '.join(self.leftnub.GetConfig()) - right = ' '.join(self.rightnub.GetConfig()) - for profileid, row in enumerate(self.profiles): - if row[0] == name: - row[1] = left - row[2] = right - self.comboentry.set_active(profileid) - break - else: - self.profiles.append([name, left, right]) - self.entry.set_text(name) + self.model.set_profile(name, self.model.settings) self.Notify("Profile saved as: %s" % name) def on_LoadProfile_clicked(self, widget, *data): - profileid = self.comboentry.get_active() - if profileid == -1: + self._lose_active() # force widget to always emit changed signals, + name = self.entry.get_text() # ok since we always lookup by text value anyway + if not name: + return + elif name not in self.model.profiles and name != DEFAULT_PROFILENAME: self.Notify("Cannot load profile, please select an existing profile.") else: - name, left, right = self.profiles[profileid] - self.leftnub.SetConfig(left.split(' ')) - self.rightnub.SetConfig(right.split(' ')) - self.Notify("Profile loaded, hit 'Apply configuration' to make it active") + self.model.load_named_profile(name) + self.Notify("Profile loaded, hit 'Write nub settings' to make it active") + + def on_DeleteProfile_clicked(self, widget, *data): + name = self.entry.get_text() + if name not in self.model.profiles or name == DEFAULT_PROFILENAME: + self.model("Cannot remove profile, please select an existing non-default profile.") + else: + dialog = gtk.MessageDialog(flags=gtk.DIALOG_MODAL, type=gtk.MESSAGE_WARNING, + buttons=gtk.BUTTONS_YES_NO, + message_format="Are you sure you want to delete profile %s?" % name) + if dialog.run() == gtk.RESPONSE_YES: + self.model.delete_profile(name) + dialog.destroy() def on_window_destroy(self, widget, *data): self.Notify("Storing profiles...") - self.write_profiles_to_file() + self.model.store_profiles(PROFILES) gtk.main_quit() +# ================================================================ + if __name__ == '__main__': parser = optparse.OptionParser() - parser.add_option('--reset', default='', - help="Reset specified nub(s). Format: left,right") - parser.add_option('-l', '--left_nub', default='', - help="Configure left nub. Format: %s. E.g. mouse,150,20,20,7,7" % ' '.join(FILES).replace(' ', ',')) - parser.add_option('-r', '--right_nub', default='', - help="Configure right nub. Format: %s. E.g. mbuttons,150,20,20,7,7" % ' '.join(FILES).replace(' ', ',')) - parser.add_option('-s', '--save_profile', default='', - help="Store current configuration as specified profile (no spaces allowed)") - parser.add_option('-p', '--load_profile', default='', - help="Load specified nub configuration profile") + parser.add_option('--reset', default=False, action='store_true', help=HELP_RESET) + parser.add_option('-l', '--left_nub', default='', help=HELP_LEFT_NUB) + parser.add_option('-r', '--right_nub', default='', help=HELP_RIGHT_NUB) + parser.add_option('-s', '--save_profile', default='', help=HELP_SAVE) + parser.add_option('-a', '--apply', default=False, action='store_true', help=HELP_APPLY) + parser.add_option('-p', '--load_profile', default='', help=HELP_LOAD) + parser.add_option('-d', '--remove_profile', default='', help=HELP_DEL) options, args = parser.parse_args() - app = NubConfig() - if len(sys.argv) == 1: # run gui app + if len(sys.argv) == 1: # no params: run gui app + app = NubConfig() gtk.main() else: # run command line app - if 'left' in options.reset: - app.on_ResetLeft_clicked(None) - if 'right' in options.reset: - app.on_ResetRight_clicked(None) - ok, values = Validate(options.left_nub) - if ok: - StoreConfigToProc(LEFT_NUB_CONFIG, values) - ok, values = Validate(options.right_nub) - if ok: - StoreConfigToProc(RIGHT_NUB_CONFIG, values) - if options.save_profile: - app.on_UndoChanges_clicked(None) - app.entry.set_text(options.save_profile) - app.on_SaveProfile_clicked(None) - app.write_profiles_to_file() + model = NubModel() + + if options.reset: + os.system(RESET_CMD) + for key, value in Validate(options.left_nub).iteritems(): + model.settings[key+'0'] = value + for key, value in Validate(options.right_nub).iteritems(): + model.settings[key+'1'] = value + if options.save_profile and options.save_profile != DEFAULT_PROFILENAME: + model.set_profile(options.save_profile, model.settings) + if options.apply: + StoreProc(model.settings) if options.load_profile: - for profileid, row in enumerate(app.profiles): - if row[0] == options.load_profile: - app.comboentry.set_active(profileid) - app.on_LoadProfile_clicked(None) - app.on_ApplyChanges_clicked(None) + model.load_named_profile(options.load_profile) + StoreProc(model.settings) + if options.remove_profile: + model.delete_profile(options.remove_profile) + if options.save_profile or options.remove_profile: + model.store_profiles(PROFILES) diff --git a/recipes/pandora-system/pandora-scripts/pndlogo.png b/recipes/pandora-system/pandora-scripts/pndlogo.png index 4fb50c1..365573e 100755 Binary files a/recipes/pandora-system/pandora-scripts/pndlogo.png and b/recipes/pandora-system/pandora-scripts/pndlogo.png differ diff --git a/recipes/pandora-system/pandora-scripts/reset_nubs.sh b/recipes/pandora-system/pandora-scripts/reset_nubs.sh new file mode 100755 index 0000000..e30ae83 --- /dev/null +++ b/recipes/pandora-system/pandora-scripts/reset_nubs.sh @@ -0,0 +1,4 @@ +#!/bin/bash +echo 1 > /sys/bus/i2c/drivers/vsense/3-0066/reset +sleep 1 +echo 0 > /sys/bus/i2c/drivers/vsense/3-0066/reset diff --git a/recipes/pandora-system/pandora-sudoers.bb b/recipes/pandora-system/pandora-sudoers.bb index bde1b56..304c328 100644 --- a/recipes/pandora-system/pandora-sudoers.bb +++ b/recipes/pandora-system/pandora-sudoers.bb @@ -5,7 +5,7 @@ COMPATIBLE_MACHINE = "omap3-pandora" RDEPENDS = "sudo" -PR = "r13" +PR = "r14" SRC_URI = " \ file://50_openpandora \ diff --git a/recipes/pandora-system/pandora-sudoers/50_openpandora b/recipes/pandora-system/pandora-sudoers/50_openpandora index 7b4324d..d7b5698 100755 --- a/recipes/pandora-system/pandora-sudoers/50_openpandora +++ b/recipes/pandora-system/pandora-sudoers/50_openpandora @@ -23,7 +23,7 @@ %wheel ALL=(ALL) NOPASSWD: /usr/pandora/scripts/op_cpusettings.sh %wheel ALL=(ALL) NOPASSWD: /usr/pandora/scripts/op_lcdrate.sh %wheel ALL=(ALL) NOPASSWD: /usr/pandora/scripts/op_videofir.sh -%wheel ALL=(ALL) NOPASSWD: /usr/pandora/scripts/op_nubmode.py +%wheel ALL=(ALL) NOPASSWD: /usr/pandora/scripts/reset_nubs.sh %wheel ALL=(ALL) NOPASSWD: /usr/pandora/scripts/op_storage.sh %wheel ALL=(ALL) NOPASSWD: /usr/pandora/scripts/op_tvout.sh %wheel ALL=(ALL) NOPASSWD: /usr/pandora/scripts/pnd_run.sh