battery *battery_get() { GError * error = NULL; const gchar *entry; GDir * dir = g_dir_open( ACPI_PATH_SYS_POWER_SUPPY, 0, &error ); battery *b = NULL; if ( dir == NULL ) { g_warning( "NO ACPI/sysfs support in kernel: %s", error->message ); return NULL; } while ( ( entry = g_dir_read_name (dir) ) != NULL ) { b = battery_new(); b->path = g_strdup( entry ); battery_update ( b ); if ( b->type_battery == TRUE ) break; /* ignore non-batteries */ else { g_free(b); b = NULL; } } g_dir_close( dir ); return b; }
/** * Update with incoming data and emit events if necessary. * @param new_state Updated core sensors state * @param cliff_data Cliff sensors readings (we include them as an extra information on cliff events) */ void EventManager::update(const CoreSensors::Data &new_state, const std::vector<uint16_t> &cliff_data) { if (last_state.buttons != new_state.buttons) { // ------------ // Button Event // ------------ // Note that the touch pad means at most one button can be pressed // at a time. ButtonEvent event; // Check changes in each button state's; even if this block of code // supports it, two buttons cannot be pressed simultaneously if ((new_state.buttons ^ last_state.buttons) & CoreSensors::Flags::Button0) { event.button = ButtonEvent::Button0; if (new_state.buttons & CoreSensors::Flags::Button0) { event.state = ButtonEvent::Pressed; } else { event.state = ButtonEvent::Released; } sig_button_event.emit(event); } if ((new_state.buttons ^ last_state.buttons) & CoreSensors::Flags::Button1) { event.button = ButtonEvent::Button1; if (new_state.buttons & CoreSensors::Flags::Button1) { event.state = ButtonEvent::Pressed; } else { event.state = ButtonEvent::Released; } sig_button_event.emit(event); } if ((new_state.buttons ^ last_state.buttons) & CoreSensors::Flags::Button2) { event.button = ButtonEvent::Button2; if (new_state.buttons & CoreSensors::Flags::Button2) { event.state = ButtonEvent::Pressed; } else { event.state = ButtonEvent::Released; } sig_button_event.emit(event); } } // ------------ // Bumper Event // ------------ if (last_state.bumper != new_state.bumper) { BumperEvent event; // Check changes in each bumper state's and raise an event if so if ((new_state.bumper ^ last_state.bumper) & CoreSensors::Flags::LeftBumper) { event.bumper = BumperEvent::Left; if (new_state.bumper & CoreSensors::Flags::LeftBumper) { event.state = BumperEvent::Pressed; } else { event.state = BumperEvent::Released; } sig_bumper_event.emit(event); } if ((new_state.bumper ^ last_state.bumper) & CoreSensors::Flags::CenterBumper) { event.bumper = BumperEvent::Center; if (new_state.bumper & CoreSensors::Flags::CenterBumper) { event.state = BumperEvent::Pressed; } else { event.state = BumperEvent::Released; } sig_bumper_event.emit(event); } if ((new_state.bumper ^ last_state.bumper) & CoreSensors::Flags::RightBumper) { event.bumper = BumperEvent::Right; if (new_state.bumper & CoreSensors::Flags::RightBumper) { event.state = BumperEvent::Pressed; } else { event.state = BumperEvent::Released; } sig_bumper_event.emit(event); } } // ------------ // Cliff Event // ------------ if (last_state.cliff != new_state.cliff) { CliffEvent event; // Check changes in each cliff sensor state's and raise an event if so if ((new_state.cliff ^ last_state.cliff) & CoreSensors::Flags::LeftCliff) { event.sensor = CliffEvent::Left; if (new_state.cliff & CoreSensors::Flags::LeftCliff) { event.state = CliffEvent::Cliff; } else { event.state = CliffEvent::Floor; } event.bottom = cliff_data[event.sensor]; sig_cliff_event.emit(event); } if ((new_state.cliff ^ last_state.cliff) & CoreSensors::Flags::CenterCliff) { event.sensor = CliffEvent::Center; if (new_state.cliff & CoreSensors::Flags::CenterCliff) { event.state = CliffEvent::Cliff; } else { event.state = CliffEvent::Floor; } event.bottom = cliff_data[event.sensor]; sig_cliff_event.emit(event); } if ((new_state.cliff ^ last_state.cliff) & CoreSensors::Flags::RightCliff) { event.sensor = CliffEvent::Right; if (new_state.cliff & CoreSensors::Flags::RightCliff) { event.state = CliffEvent::Cliff; } else { event.state = CliffEvent::Floor; } event.bottom = cliff_data[event.sensor]; sig_cliff_event.emit(event); } } // ------------ // Wheel Drop Event // ------------ if (last_state.wheel_drop != new_state.wheel_drop) { WheelEvent event; // Check changes in each wheel_drop sensor state's and raise an event if so if ((new_state.wheel_drop ^ last_state.wheel_drop) & CoreSensors::Flags::LeftWheel) { event.wheel = WheelEvent::Left; if (new_state.wheel_drop & CoreSensors::Flags::LeftWheel) { event.state = WheelEvent::Dropped; } else { event.state = WheelEvent::Raised; } sig_wheel_event.emit(event); } if ((new_state.wheel_drop ^ last_state.wheel_drop) & CoreSensors::Flags::RightWheel) { event.wheel = WheelEvent::Right; if (new_state.wheel_drop & CoreSensors::Flags::RightWheel) { event.state = WheelEvent::Dropped; } else { event.state = WheelEvent::Raised; } sig_wheel_event.emit(event); } } // ------------ // Power System Event // ------------ if (last_state.charger != new_state.charger) { Battery battery_new(new_state.battery, new_state.charger); Battery battery_last(last_state.battery, last_state.charger); if (battery_last.charging_state != battery_new.charging_state) { PowerEvent event; switch (battery_new.charging_state) { case Battery::Discharging: event.event = PowerEvent::Unplugged; break; case Battery::Charged: event.event = PowerEvent::ChargeCompleted; break; case Battery::Charging: if (battery_new.charging_source == Battery::Adapter) event.event = PowerEvent::PluggedToAdapter; else event.event = PowerEvent::PluggedToDockbase; break; } sig_power_event.emit(event); } } if (last_state.battery > new_state.battery) { Battery battery_new(new_state.battery, new_state.charger); Battery battery_last(last_state.battery, last_state.charger); if (battery_last.level() != battery_new.level()) { PowerEvent event; switch (battery_new.level()) { case Battery::Low: event.event = PowerEvent::BatteryLow; break; case Battery::Dangerous: event.event = PowerEvent::BatteryCritical; break; default: break; } sig_power_event.emit(event); } } last_state = new_state; }
battery *battery_get(int battery_number) { GError * error = NULL; const gchar *entry; gchar *batt_name = NULL; gchar *batt_path = NULL; GDir * dir; battery *b = NULL; /* Try the expected path in sysfs first */ batt_name = g_strdup_printf(ACPI_BATTERY_DEVICE_NAME "%d", battery_number); batt_path = g_strdup_printf(ACPI_PATH_SYS_POWER_SUPPLY "/%s", batt_name); if (g_file_test(batt_path, G_FILE_TEST_IS_DIR) == TRUE) { b = battery_new(); b->path = g_strdup( batt_name); battery_update ( b ); if (!b->type_battery) { g_warning( "Not a battery: %s", batt_path ); battery_free(b); b = NULL; } } g_free(batt_name); g_free(batt_path); if (b != NULL) return b; /* * We didn't find the expected path in sysfs. * Walk the dir and return any battery. */ dir = g_dir_open( ACPI_PATH_SYS_POWER_SUPPLY, 0, &error ); if ( dir == NULL ) { g_warning( "NO ACPI/sysfs support in kernel: %s", error->message ); g_error_free(error); return NULL; } while ( ( entry = g_dir_read_name (dir) ) != NULL ) { b = battery_new(); b->path = g_strdup( entry ); battery_update ( b ); /* We're looking for a battery with the selected ID */ if (b->type_battery == TRUE) { break; } battery_free(b); b = NULL; } if (b != NULL) g_warning( "Battery entry " ACPI_BATTERY_DEVICE_NAME "%d not found, using %s", battery_number, b->path); // FIXME: update config? else g_warning( "Battery %d not found", battery_number ); g_dir_close( dir ); return b; }