gboolean is_store_set_label(IsStore *self, GtkTreeIter *iter, const gchar *label) { IsStorePrivate *priv; IsStoreEntry *entry = NULL; gboolean ret = FALSE; g_return_val_if_fail(IS_IS_STORE(self), FALSE); g_return_val_if_fail(iter != NULL, FALSE); priv = self->priv; g_return_val_if_fail(iter->stamp == priv->stamp, FALSE); g_return_val_if_fail(iter->user_data, FALSE); entry = (IsStoreEntry *)g_sequence_get(iter->user_data); if (entry->sensor && g_strcmp0(is_sensor_get_label(entry->sensor), label) != 0) { GtkTreePath *path; is_sensor_set_label(entry->sensor, label); path = gtk_tree_model_get_path(GTK_TREE_MODEL(self), iter); gtk_tree_model_row_changed(GTK_TREE_MODEL(self), path, iter); gtk_tree_path_free(path); ret = TRUE; } return ret; }
static void sensor_notify_label(IsSensor *sensor, GParamSpec *pspec, IsSensorDialog *self) { gtk_entry_set_text(GTK_ENTRY(self->priv->label_entry), is_sensor_get_label(sensor)); }
static void _is_store_get_value(GtkTreeModel *tree_model, GtkTreeIter *iter, gint column, GValue *value) { IsStore *self; IsStorePrivate *priv; IsStoreEntry *entry = NULL; g_return_if_fail(IS_IS_STORE(tree_model)); g_return_if_fail(iter != NULL); self = IS_STORE(tree_model); priv = self->priv; g_return_if_fail(iter->stamp == priv->stamp); g_assert(iter->user_data); g_value_init(value, column_types[column]); entry = (IsStoreEntry *) g_sequence_get((GSequenceIter *)iter->user_data); g_assert(entry); switch (column) { case IS_STORE_COL_NAME: g_value_set_string(value, entry->name); break; case IS_STORE_COL_LABEL: g_value_set_string(value, (entry->sensor ? is_sensor_get_label(entry->sensor) : NULL)); break; case IS_STORE_COL_IS_SENSOR: g_value_set_boolean(value, (entry->sensor != NULL)); break; case IS_STORE_COL_SENSOR: g_value_set_object(value, entry->sensor); break; case IS_STORE_COL_ENABLED: g_value_set_boolean(value, entry->enabled); break; case IS_STORE_COL_ICON: g_value_set_string(value, (entry->sensor ? is_sensor_get_icon(entry->sensor) : NULL)); break; default: g_assert_not_reached(); } }
static void on_sensor_value_notify(IsSensor *sensor, GParamSpec *pspec, gpointer user_data) { IsMaxPlugin *self; IsMaxPluginPrivate *priv; gdouble value; self = IS_MAX_PLUGIN(user_data); priv = self->priv; value = is_sensor_get_value(sensor); if (value - IS_SENSOR_VALUE_UNSET <= DBL_EPSILON) { is_debug("max", "sensor value for sensor %s is unset - ignoring", is_sensor_get_label(sensor)); goto exit; } if (value > priv->max_value && sensor != priv->max) { // let's see if we can get away without taking a reference on sensor priv->max = sensor; is_message("max", "New highest value sensor: %s (value %f)", is_sensor_get_label(sensor), value); } if (sensor == priv->max) { priv->max_value = value; update_sensor_from_max(self); } exit: return; }
static void update_sensor_from_max(IsMaxPlugin *self) { IsMaxPluginPrivate *priv; gchar *label; priv = self->priv; label = g_strdup_printf("↑%s", is_sensor_get_label(priv->max)); is_sensor_set_label(priv->sensor, label); is_sensor_set_icon(priv->sensor, is_sensor_get_icon(priv->max)); is_sensor_set_value(priv->sensor, is_sensor_get_value(priv->max)); is_sensor_set_units(priv->sensor, is_sensor_get_units(priv->max)); is_sensor_set_digits(priv->sensor, is_sensor_get_digits(priv->max)); g_free(label); }
static void on_sensor_enabled(IsManager *manager, IsSensor *sensor, gint index, gpointer data) { IsMaxPlugin *self = (IsMaxPlugin *)data; // don't bother monitoring non-temperature sensors if (IS_IS_TEMPERATURE_SENSOR(sensor)) { is_debug("max", "sensor enabled: %s", is_sensor_get_label(sensor)); on_sensor_value_notify(sensor, NULL, self); g_signal_connect(sensor, "notify::value", G_CALLBACK(on_sensor_value_notify), self); } }
static void on_sensor_disabled(IsManager *manager, IsSensor *sensor, gpointer data) { IsMaxPlugin *self = (IsMaxPlugin *)data; IsMaxPluginPrivate *priv = self->priv; // don't bother monitoring non-temperature sensors if (IS_IS_TEMPERATURE_SENSOR(sensor)) { is_debug("max", "sensor disabled: %s", is_sensor_get_label(sensor)); g_signal_handlers_disconnect_by_func(sensor, G_CALLBACK(on_sensor_value_notify), self); if (priv->max == sensor) { // get all sensors and find the one with the maximum value and switch to // this GSList *sensors, *_list; priv->max = NULL; priv->max_value = 0.0; is_sensor_set_label(priv->sensor, "Δ"); is_sensor_set_icon(priv->sensor, IS_STOCK_CHIP); is_sensor_set_value(priv->sensor, 0.0); is_sensor_set_units(priv->sensor, ""); is_sensor_set_digits(priv->sensor, 1); sensors = is_manager_get_enabled_sensors_list(manager); for (_list = sensors; _list != NULL; _list = _list->next) { if (IS_IS_TEMPERATURE_SENSOR(_list->data)) { on_sensor_value_notify(IS_SENSOR(_list->data), NULL, self); } } } } }
static void is_sensor_dialog_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) { IsSensorDialog *self = IS_SENSOR_DIALOG(object); IsSensorDialogPrivate *priv = self->priv; gchar *markup; switch (property_id) { case PROP_SENSOR: priv->sensor = g_object_ref(g_value_get_object(value)); markup = g_strdup_printf("<span weight='bold'>%s: %s</span>", _("Sensor"), is_sensor_get_path(priv->sensor)); gtk_label_set_markup(GTK_LABEL(priv->path_label), markup); g_free(markup); gtk_widget_set_sensitive(priv->label_entry, TRUE); gtk_entry_set_text(GTK_ENTRY(priv->label_entry), is_sensor_get_label(priv->sensor)); g_signal_connect(priv->label_entry, "changed", G_CALLBACK(label_changed), self); g_signal_connect(priv->sensor, "notify::label", G_CALLBACK(sensor_notify_label), self); gtk_widget_set_sensitive(priv->alarm_mode_combo_box, TRUE); gtk_combo_box_set_active(GTK_COMBO_BOX(priv->alarm_mode_combo_box), is_sensor_get_alarm_mode(priv->sensor)); g_signal_connect(priv->alarm_mode_combo_box, "changed", G_CALLBACK(alarm_mode_changed), self); g_signal_connect(priv->sensor, "notify::alarm-mode", G_CALLBACK(sensor_notify_alarm_mode), self); /* set sensitive so we can update */ gtk_widget_set_sensitive(priv->alarm_value_spin_button, TRUE); gtk_spin_button_set_digits(GTK_SPIN_BUTTON(priv->alarm_value_spin_button), is_sensor_get_digits(priv->sensor)); gtk_spin_button_set_value(GTK_SPIN_BUTTON(priv->alarm_value_spin_button), is_sensor_get_alarm_value(priv->sensor)); g_signal_connect(priv->alarm_value_spin_button, "value-changed", G_CALLBACK(alarm_value_changed), self); g_signal_connect(priv->sensor, "notify::alarm-value", G_CALLBACK(sensor_notify_alarm_value), self); gtk_widget_set_sensitive(priv->alarm_value_spin_button, (is_sensor_get_alarm_mode(priv->sensor) != IS_SENSOR_ALARM_MODE_DISABLED)); gtk_widget_set_sensitive(priv->units_label, TRUE); gtk_label_set_text(GTK_LABEL(priv->units_label), is_sensor_get_units(priv->sensor)); g_signal_connect(priv->sensor, "notify::units", G_CALLBACK(sensor_notify_units), self); gtk_widget_set_sensitive(priv->low_value, TRUE); gtk_spin_button_set_value(GTK_SPIN_BUTTON(priv->low_value), is_sensor_get_low_value(priv->sensor)); g_signal_connect(priv->low_value, "value-changed", G_CALLBACK(low_value_changed), self); g_signal_connect(priv->sensor, "notify::low-value", G_CALLBACK(sensor_notify_low_value), self); gtk_label_set_text(GTK_LABEL(priv->low_units_label), is_sensor_get_units(priv->sensor)); gtk_widget_set_sensitive(priv->high_value, TRUE); gtk_spin_button_set_value(GTK_SPIN_BUTTON(priv->high_value), is_sensor_get_high_value(priv->sensor)); g_signal_connect(priv->high_value, "value-changed", G_CALLBACK(high_value_changed), self); g_signal_connect(priv->sensor, "notify::high-value", G_CALLBACK(sensor_notify_high_value), self); gtk_label_set_text(GTK_LABEL(priv->high_units_label), is_sensor_get_units(priv->sensor)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); break; } }
static void update_sensor_menu_item_label(IsIndicator *self, IsSensor *sensor, GtkMenuItem *menu_item) { gchar *text; text = g_strdup_printf("%s %2.*f%s", is_sensor_get_label(sensor), is_sensor_get_digits(sensor), is_sensor_get_value(sensor), is_sensor_get_units(sensor)); gtk_menu_item_set_label(menu_item, text); g_free(text); text = NULL; #if HAVE_APPINDICATOR if (sensor == self->priv->primary) { IsIndicatorPrivate *priv = self->priv; gboolean connected; g_object_get(self, "connected", &connected, NULL); /* using fallback so just set icon */ if (!connected) { app_indicator_set_icon_full(APP_INDICATOR(self), PACKAGE, is_sensor_get_label(sensor)); return; } if (priv->display_flags & IS_INDICATOR_DISPLAY_VALUE) { text = g_strdup_printf("%2.*f%s", is_sensor_get_digits(sensor), is_sensor_get_value(sensor), is_sensor_get_units(sensor)); } if (priv->display_flags & IS_INDICATOR_DISPLAY_LABEL) { /* join label to existing text - if text is NULL this will just show label */ text = g_strjoin(" ", is_sensor_get_label(sensor), text, NULL); } if (priv->display_flags & IS_INDICATOR_DISPLAY_ICON) { app_indicator_set_icon_full(APP_INDICATOR(self), is_sensor_get_icon_path(sensor), is_sensor_get_label(sensor)); } else { /* set to a 1x1 transparent icon for no icon */ app_indicator_set_icon_full(APP_INDICATOR(self), "indicator-sensors-no-icon", is_sensor_get_label(sensor)); } app_indicator_set_label(APP_INDICATOR(self), text, text); g_free(text); app_indicator_set_status(APP_INDICATOR(self), is_sensor_get_alarmed(sensor) ? APP_INDICATOR_STATUS_ATTENTION : APP_INDICATOR_STATUS_ACTIVE); } #else gtk_status_icon_set_from_icon_name(GTK_STATUS_ICON(self), PACKAGE); #endif }
gboolean is_store_add_sensor(IsStore *self, IsSensor *sensor, GtkTreeIter *iter) { IsStorePrivate *priv; GSequence *entries; IsStoreEntry *entry = NULL; GSequenceIter *parent = NULL; gchar **names = NULL; int i; GtkTreePath *path; GtkTreeIter _iter; gboolean ret = FALSE; g_return_val_if_fail(IS_IS_STORE(self), FALSE); g_return_val_if_fail(IS_IS_SENSOR(sensor), FALSE); priv = self->priv; entry = find_entry(self, is_sensor_get_path(sensor)); if (entry) { is_warning("store", "sensor %s already exists in store, not adding duplicate", is_sensor_get_path(sensor)); goto out; } entries = priv->entries; names = g_strsplit(is_sensor_get_path(sensor), "/", 0); /* otherwise iterate through to create the entry */ for (i = 0; names[i] != NULL; i++) { GSequenceIter *seq_iter; gchar *name = names[i]; entry = NULL; for (seq_iter = g_sequence_get_begin_iter(entries); !g_sequence_iter_is_end(seq_iter); seq_iter = g_sequence_iter_next(seq_iter)) { entry = (IsStoreEntry *)g_sequence_get(seq_iter); if (g_strcmp0(entry->name, name) == 0) { entries = entry->entries; parent = seq_iter; break; } entry = NULL; } if (!entry) { /* create entry for this name component */ entry = entry_new(name); entry->iter = g_sequence_append(entries, entry); entry->parent = parent; entries = entry->entries; _iter.stamp = priv->stamp; _iter.user_data = entry->iter; path = gtk_tree_model_get_path(GTK_TREE_MODEL(self), &_iter); gtk_tree_model_row_inserted(GTK_TREE_MODEL(self), path, &_iter); gtk_tree_path_free(path); /* parent of the next entry we create will be this * entry */ parent = entry->iter; } } g_strfreev(names); g_assert(entry); g_assert(find_entry(self, is_sensor_get_path(sensor)) == entry); is_debug("store", "inserted sensor %s with label %s", is_sensor_get_path(sensor), is_sensor_get_label(sensor)); entry->sensor = g_object_ref(sensor); _iter.stamp = priv->stamp; _iter.user_data = entry->iter; path = gtk_tree_model_get_path(GTK_TREE_MODEL(self), &_iter); gtk_tree_model_row_changed(GTK_TREE_MODEL(self), path, &_iter); gtk_tree_path_free(path); /* return a copy of iter */ if (iter != NULL) { iter->stamp = priv->stamp; iter->user_data = entry->iter; } ret = TRUE; out: return ret; }
static void on_sensor_value_notify(IsSensor *sensor, GParamSpec *pspec, gpointer user_data) { IsDynamicPlugin *self; IsDynamicPluginPrivate *priv; RateData *data; gdouble value, dv, dt, rate; gint64 now; self = IS_DYNAMIC_PLUGIN(user_data); priv = self->priv; value = is_sensor_get_value(sensor); if (value - IS_SENSOR_VALUE_UNSET <= DBL_EPSILON) { is_debug("dynamic", "sensor value for sensor %s is unset - ignoring", is_sensor_get_label(sensor)); goto exit; } now = g_get_monotonic_time(); data = g_object_get_data(G_OBJECT(sensor), DYNAMIC_RATE_DATA_KEY); if (data == NULL) { is_debug("dynamic", "Creating new dynamic rate data for sensor: %s", is_sensor_get_label(sensor)); // allocate data data = g_malloc0(sizeof(*data)); data->rate = 0.0f; data->last_value = value; data->last_time = now; g_object_set_data_full(G_OBJECT(sensor), DYNAMIC_RATE_DATA_KEY, data, g_free); goto exit; } is_debug("dynamic", "Got existing rate data for sensor: %s - rate: %f, last_value %f, last_time %"PRId64"", is_sensor_get_label(sensor), data->rate, data->last_value, data->last_time); dv = value - data->last_value; dt = ((double)(now - data->last_time) / (double)G_USEC_PER_SEC); // convert rate to units per second rate = fabs(dv / dt); is_debug("dynamic", "abs rate of change of sensor %s: %f (t0: %f, t-1: %f, dv: %f, dt: %f)", is_sensor_get_label(sensor), rate, value, data->last_value, dv, dt); // calculate exponentially weighted moving average of rate rate = (EWMA_ALPHA * rate) + ((1 - EWMA_ALPHA) * data->rate); data->rate = rate; data->last_value = value; data->last_time = now; is_debug("dynamic", "EWMA abs rate of change of sensor %s: %f", is_sensor_get_label(sensor), rate); if (rate > priv->max_rate && sensor != priv->max) { // let's see if we can get away without taking a reference on sensor priv->max = sensor; is_message("dynamic", "New highest EWMA rate sensor: %s (rate %f)", is_sensor_get_label(sensor), rate); } if (sensor == priv->max) { priv->max_rate = rate; update_sensor_from_max(self); } exit: return; }