def update_track(self): self._get_elapsed() self.playback_started = time.time() self.check_status() if self.status == "Playing": self.timer = g15scheduler.queue("mprisDataQueue-%s" % self.screen.device.uid, "UpdateTrackData", 1.0, self.update_track) else: self.timer = g15scheduler.queue("mprisDataQueue-%s" % self.screen.device.uid, "UpdateTrackData", 5.0, self.update_track)
def __init__(self, gconf_client, screen, players, bus_name, session_bus, theme): self.timer = None root_obj = session_bus.get_object(bus_name, '/') root = dbus.Interface(root_obj, 'org.freedesktop.MediaPlayer') AbstractMPRISPlayer.__init__(self, gconf_client, screen, players, bus_name, session_bus, root.Identity(), theme) # There is no seek / position changed event in MPRIS1, so we poll player_obj = session_bus.get_object(bus_name, '/Player') self.player = dbus.Interface(player_obj, 'org.freedesktop.MediaPlayer') # Set the initial status self._get_elapsed() self.check_status() # Start polling for status, position and track changes self.timer = g15scheduler.queue( "mprisDataQueue-%s" % self.screen.device.uid, "UpdateTrackData", 1.0, self.update_track) session_bus.add_signal_receiver( self.track_changed_handler, dbus_interface="org.freedesktop.MediaPlayer", signal_name="TrackChange")
def acquire_control(self, control, release_after = None, val = None, on_release = None): control_acquisitions = self.acquired_controls[control.id] if control.id in self.acquired_controls else [] self.acquired_controls[control.id] = control_acquisitions if len(control_acquisitions) == 0: self.initial_acquired_control_values[control.id] = control.value control_acquisition = ControlAcquisition(self, control) control_acquisition.on_release = on_release control_acquisitions.append(control_acquisition) # Only set the value when active (i.e. in the control_acquisitions list) control_acquisition.set_value(val if val is not None else control.value) if release_after: g15scheduler.queue(FX_QUEUE, "ReleaseControl", release_after, self._release_control, control_acquisition) return control_acquisition
def _schedule_redraw(self): if self.active: next_tick = self.refresh_interval if self.painter.is_idle(): next_tick = 1.0 self.timer = g15scheduler.queue("impulseQueue", "ImpulseRedraw", next_tick, self.redraw)
def _reduce(self, interval, target_val, release, step): if not self.fade_cancelled: if isinstance(self.val, int): AbstractControlAcquisition._reduce(self, interval, target_val, release, step) else: if self.val > target_val: h, s, v = self.rgb_to_hsv(self.val) v = max(0, v - step) new_rgb = self.hsv_to_rgb((h, s, v)) if new_rgb == self.val: new_rgb = target_val self.set_value(new_rgb) if self.val <= target_val: if release and not self._released: self.driver.release_control(self) else: g15scheduler.queue(FX_QUEUE, "Fade", interval, self._reduce, interval, target_val, release, step)
def _repeat_uinput(self, macro, uc, uinput_repeat=False): if macro in self.__repeat_macros: self._send_uinput_keypress(macro, uc, uinput_repeat) if macro in self.__repeat_macros: self.__macro_repeat_timer = g15scheduler.queue( self.queue_name, "MacroRepeat", macro.repeat_delay, self._repeat_uinput, self._reload_macro_instance(macro), uc, uinput_repeat)
def _reduce(self, interval, target_val, release, step): if not self.fade_cancelled: if self.val > target_val: self.set_value(self.val - step) if self.val == target_val: if release: self.driver.release_control(self) else: self.fade_timer = g15scheduler.queue(FX_QUEUE, "Fade", interval, self._reduce, interval, target_val, release, step)
def _handle_macro(self, macro, state, key_states, repetition=False): self._consume_keys(key_states) delay = macro.repeat_delay if macro.repeat_delay != -1 else 0.1 if macro.repeat_mode == g15profile.REPEAT_TOGGLE and state == g15driver.KEY_STATE_UP: if macro in self.__repeat_macros and not repetition: # Key pressed again, so stop repeating self.__cancel_macro_repeat_timer() self.__repeat_macros.remove(macro) else: if not macro in self.__repeat_macros and not repetition: self.__repeat_macros.append(macro) else: self._process_macro(macro, state, key_states) # We test again because a toggle might have stopped the repeat if macro in self.__repeat_macros: self.__macro_repeat_timer = g15scheduler.queue( self.queue_name, "RepeatMacro", delay, self._handle_macro, macro, state, key_states, True) elif macro.repeat_mode == g15profile.REPEAT_WHILE_HELD and not state == g15driver.KEY_STATE_DOWN: if state == g15driver.KEY_STATE_UP and macro in self.__repeat_macros and not repetition: # Key released again, so stop repeating self.__cancel_macro_repeat_timer() self.__repeat_macros.remove(macro) else: if state == g15driver.KEY_STATE_HELD and not macro in self.__repeat_macros and not repetition: self.__repeat_macros.append(macro) self._process_macro(macro, state, key_states) # We test again because a toggle might have stopped the repeat if macro in self.__repeat_macros: self.__macro_repeat_timer = g15scheduler.queue( self.queue_name, "RepeatMacro", delay, self._handle_macro, macro, g15driver.KEY_STATE_HELD, key_states, True) elif state == g15driver.KEY_STATE_DOWN and macro.activate_on == g15driver.KEY_STATE_DOWN: self._process_macro(macro, state, key_states) elif state == g15driver.KEY_STATE_UP and macro.activate_on == g15driver.KEY_STATE_UP: self._process_macro(macro, state, key_states) elif state == g15driver.KEY_STATE_HELD and macro.activate_on == g15driver.KEY_STATE_HELD: self._process_macro(macro, state, key_states) # Also defeat the key release so any normal KEY_STATE_UP macros don't get activated as well self._defeat_release(key_states)
def blink(self, off_val = 0, delay = 0.5, duration = None, blink_started = None): if blink_started == None: blink_started = time.time() self.cancel_fade() self.cancel_reset() if self.on: self.adjust(self.val) else: self.adjust(off_val if isinstance(off_val, int) or isinstance(off_val, tuple) else off_val()) self.on = not self.on if duration == None or time.time() < blink_started + duration: self.reset_timer = g15scheduler.queue(FX_QUEUE, "Blink", delay, self.blink, off_val, delay, duration, blink_started) return self.reset_timer
def _handle_uinput_macros(self): """ Search for all the uinput macros that would be activated by the current key state, and emit events of the same type. """ uinput_repeat = False for m in self.__uinput_macros: down = [] up = [] held = [] for k in m.keys: if k in self.__key_states: key_state = self.__key_states[k] if not key_state.is_consumed(): if key_state.state_id == g15driver.KEY_STATE_UP and not key_state.defeat_release: up.append(key_state) if key_state.state_id == g15driver.KEY_STATE_DOWN: down.append(key_state) if key_state.state_id == g15driver.KEY_STATE_HELD: held.append(key_state) if len(down) == len(m.keys): self._handle_uinput_macro(m, g15driver.KEY_STATE_DOWN, down) if len(up) == len(m.keys): self._handle_uinput_macro(m, g15driver.KEY_STATE_UP, up) if len(held) == len(m.keys): self._handle_uinput_macro(m, g15driver.KEY_STATE_HELD, held) uinput_repeat = True """ Simulate a uinput repeat by just handling an empty key list. No keys have changed state, so we should just keep hitting this reschedule until they do """ if uinput_repeat: g15scheduler.queue(self.queue_name, "RepeatUinput", \ 0.1, \ self._handle_uinput_macros)
def _configure_key_state(self, key, state_id): """ Maintains the "key state" table, which holds what state each key is currently in. This function will return the number of state changes, so this key event may be ignored if it is no longer appropriate (i.e. a hold timer event for keys that are now released) Keyword arguments: key -- single key state_id -- state_id (g15driver.KEY_STATE_UP, _DOWN or _HELD) """ if state_id == g15driver.KEY_STATE_HELD and not key in self.__key_states: """ All keys were released before the HOLD timer kicked in, so we totally ignore this key """ pass else: if not key in self.__key_states: self.__key_states[key] = KeyState(key) key_state = self.__key_states[key] # This is a new key press, so reset this key's consumed state key_state.consumed = False # Check the sanity of the key press self._check_key_state(state_id, key_state) key_state.state_id = state_id if state_id == g15driver.KEY_STATE_DOWN: """ Key is now down, let's set up a timer to produce a held event """ key_state.timer = g15scheduler.queue(self.queue_name, "HoldKey%s" % str(key), \ self.__screen.service.key_hold_duration, \ self._do_key_received, [ key ], \ g15driver.KEY_STATE_HELD) elif state_id == g15driver.KEY_STATE_UP: """ Now the key is up, cancel the HELD timer if one exists. """ key_state.cancel_timer() return True
def __init__(self, gconf_client, screen, players, bus_name, session_bus, theme): self.timer = None root_obj = session_bus.get_object(bus_name, '/') root = dbus.Interface(root_obj, 'org.freedesktop.MediaPlayer') AbstractMPRISPlayer.__init__(self, gconf_client, screen, players, bus_name, session_bus, root.Identity(), theme) # There is no seek / position changed event in MPRIS1, so we poll player_obj = session_bus.get_object(bus_name, '/Player') self.player = dbus.Interface(player_obj, 'org.freedesktop.MediaPlayer') # Set the initial status self._get_elapsed() self.check_status() # Start polling for status, position and track changes self.timer = g15scheduler.queue("mprisDataQueue-%s" % self.screen.device.uid, "UpdateTrackData", 1.0, self.update_track) session_bus.add_signal_receiver(self.track_changed_handler, dbus_interface = "org.freedesktop.MediaPlayer", signal_name = "TrackChange")
def __init__(self, gconf_client, screen, players, bus_name, session_bus, theme): self.last_properties = None self.tracks = [] # Connect to DBUS player_obj = session_bus.get_object(bus_name, '/org/mpris/MediaPlayer2') self.player = dbus.Interface(player_obj, 'org.mpris.MediaPlayer2.Player') self.player_properties = dbus.Interface(player_obj, 'org.freedesktop.DBus.Properties') try: identity = self.player_properties.Get("org.mpris.MediaPlayer2", "Identity") except DBusException as e: logger.debug("Error getting identify of player. Using default indentify.", exc_info = e) # Set a default identity if we cannot get players identity Identity = "MPRIS2" # Connect to DBUS self.track_list = None self.track_list_properties = None try: self.track_list = dbus.Interface(player_obj, 'org.mpris.MediaPlayer2.TrackList') self.track_list_properties = dbus.Interface(self.track_list, 'org.freedesktop.DBus.Properties') self.load_track_list() except ( dbus.DBusException, KeyError ) as e: logger.debug("Cound not load track list", exc_info = e) pass if self.track_list is None: logger.info("No TrackList interface") # Configure the initial state AbstractMPRISPlayer.__init__(self, gconf_client, screen, players, bus_name, session_bus, identity, theme) session_bus.add_signal_receiver(self.properties_changed_handler, dbus_interface = "org.freedesktop.DBus.Properties", signal_name = "PropertiesChanged") session_bus.add_signal_receiver(self.seeked, dbus_interface = "org.mpris.MediaPlayer2.Player", signal_name = "Seeked") # Set the initial status self.check_status() # Workarounds self.timer = None # xnoise doesn't send seeked signals, so we need to refresh if "xnoise" in bus_name: self.timer = g15scheduler.queue("mprisDataQueue-%s" % self.screen.device.uid, "UpdateTrackData", 1.0, self.update_track)
def set_value(self, val, reset_after = None): old_val = val if self.val is None or val != self.val or reset_after is not None: if self.val is None: logger.debug("Initial value of control is %s", str(val)) self.reset_val = val self.val = val self.on = True self.cancel_fade() self.adjust(val) self.cancel_reset() logger.debug("Set value of control to %s", str(val)) if reset_after: self.reset_val = old_val self.reset_timer = g15scheduler.queue(FX_QUEUE, "LEDReset", reset_after, self.reset) return self.reset_timer
def _config_changed(self, client, connection_id, entry, args): ''' If the user changes the soundcard on the preferences dialog this method would be called two times. A first time for the soundcard change, and a second time because the first mixer of the newly selected soundcard is automatically selected. The volume monitoring would then be restarted twice, which makes no sense. Instead of restarting the monitoring as soon as this method is called, we put it as a task on a queue for 1 second. If during that time, any other change happens to the configuration, the previous restart request is cancelled, and another one takes it's place. This way, the monitoring is only restarted once when the user selects another sound card. ''' if self._reload_config_timer is not None: if not self._reload_config_timer.is_complete(): self._reload_config_timer.cancel() self._reload_config_timer = None self._reload_config_timer = g15scheduler.queue( 'VolumeMonitorQueue', 'RestartVolumeMonitoring', 1.0, self._restart_monitoring)
def _config_changed(self, client, connection_id, entry, args): ''' If the user changes the soundcard on the preferences dialog this method would be called two times. A first time for the soundcard change, and a second time because the first mixer of the newly selected soundcard is automatically selected. The volume monitoring would then be restarted twice, which makes no sense. Instead of restarting the monitoring as soon as this method is called, we put it as a task on a queue for 1 second. If during that time, any other change happens to the configuration, the previous restart request is cancelled, and another one takes it's place. This way, the monitoring is only restarted once when the user selects another sound card. ''' if self._reload_config_timer is not None: if not self._reload_config_timer.is_complete(): self._reload_config_timer.cancel() self._reload_config_timer = None self._reload_config_timer = g15scheduler.queue('VolumeMonitorQueue', 'RestartVolumeMonitoring', 1.0, self._restart_monitoring)
def Stop(self): g15scheduler.queue("serviceQueue", "dbusShutdown", 0, self._service.shutdown)
def update_track(self): logger.debug("Updating elapsed time") self.reset_elapsed() self.timer = g15scheduler.queue( "mprisDataQueue-%s" % self.screen.device.uid, "UpdateTrackData", 1.0 if self.status == "Playing" else 5.0, self.update_track)
def track_changed_handler(self, detail): g15scheduler.queue("mprisDataQueue-%s" % self.screen.device.uid, "LoadTrackDetails", 1.0, self.load_and_draw)
def schedule_redraw(self): self.cancel_redraw() self.redraw_timer = g15scheduler.queue("mprisDataQueue-%s" % self.screen.device.uid, "MPRIS2Redraw", 1.0, self.redraw)
def schedule_redraw(self): self.cancel_redraw() self.redraw_timer = g15scheduler.queue( "mprisDataQueue-%s" % self.screen.device.uid, "MPRIS2Redraw", 1.0, self.redraw)
def schedule_refresh(self, time = - 1): if time == -1: time = get_update_time(self.gconf_client, self.gconf_key) * 60.0 self.refresh_timer = g15scheduler.queue("lcdbiff-%s" % self.screen.device.uid, "MailRefreshTimer", time, self.refresh)
def update_track(self): logger.debug("Updating elapsed time") self.reset_elapsed() self.timer = g15scheduler.queue("mprisDataQueue-%s" % self.screen.device.uid, "UpdateTrackData", 1.0 if self.status == "Playing" else 5.0, self.update_track)