static gboolean up_devd_event_cb (GIOChannel *source, GIOCondition condition, gpointer user_data) { gchar *event; gsize terminator; GIOStatus status; status = g_io_channel_read_line(source, &event, NULL, &terminator, NULL); if (status == G_IO_STATUS_NORMAL) { event[terminator] = 0; up_devd_process_event(event, user_data); g_free(event); } else if (status == G_IO_STATUS_AGAIN) { up_devd_init (UP_BACKEND(user_data)); if (up_devd_inited) { int fd; fd = g_io_channel_unix_get_fd (source); g_io_channel_shutdown (source, FALSE, NULL); close (fd); return FALSE; } } return TRUE; }
/** * up_backend_new: * * Return value: a new %UpBackend object. **/ UpBackend * up_backend_new (void) { UpBackend *backend; backend = g_object_new (UP_TYPE_BACKEND, NULL); return UP_BACKEND (backend); }
/* callback updating the device */ static gboolean up_backend_apm_powerchange_event_cb(gpointer object) { UpBackend *backend; g_return_val_if_fail (UP_IS_BACKEND (object), FALSE); backend = UP_BACKEND (object); up_apm_device_refresh(backend->priv->ac); up_apm_device_refresh(backend->priv->battery); /* return false to not endless loop */ return FALSE; }
static void up_devd_process_event (const gchar *event, gpointer user_data) { UpBackend *backend; g_return_if_fail(event != NULL); backend = UP_BACKEND(user_data); g_debug("received devd event: '%s'", event); switch (event[0]) { case UP_DEVD_EVENT_ADD: case UP_DEVD_EVENT_REMOVE: /* Do nothing as we don't currently hotplug ACPI devices. */ return; case UP_DEVD_EVENT_NOTIFY: { gchar *system; gchar *subsystem; gchar *type; gchar *data; if (!up_devd_parse_notify (event + 1, &system, &subsystem, &type, &data)) goto malformed; up_devd_process_notify_event (backend, system, subsystem, type, data); g_free (system); g_free (subsystem); g_free (type); g_free (data); } return; case UP_DEVD_EVENT_NOMATCH: /* Do nothing. */ return; } malformed: g_warning("malformed devd event: %s", event); }
/** * up_backend_finalize: **/ static void up_backend_finalize (GObject *object) { UpBackend *backend; g_return_if_fail (UP_IS_BACKEND (object)); backend = UP_BACKEND (object); if (backend->priv->daemon != NULL) g_object_unref (backend->priv->daemon); if (backend->priv->battery != NULL) g_object_unref (backend->priv->battery); if (backend->priv->ac != NULL) g_object_unref (backend->priv->ac); /* XXX stop apm_thread ? */ G_OBJECT_CLASS (up_backend_parent_class)->finalize (object); }
/* thread doing kqueue() on apm device */ static gpointer up_backend_apm_event_thread(gpointer object) { int kq, nevents; struct kevent ev; struct timespec ts = {600, 0}, sts = {0, 0}; UpBackend *backend; g_return_val_if_fail (UP_IS_BACKEND (object), NULL); backend = UP_BACKEND (object); g_debug("setting up apm thread"); kq = kqueue(); if (kq <= 0) g_error("kqueue"); EV_SET(&ev, up_apm_get_fd(), EVFILT_READ, EV_ADD | EV_ENABLE | EV_CLEAR, 0, 0, NULL); nevents = 1; if (kevent(kq, &ev, nevents, NULL, 0, &sts) < 0) g_error("kevent"); /* blocking wait on kqueue */ for (;;) { int rv; /* 10mn timeout */ sts = ts; if ((rv = kevent(kq, NULL, 0, &ev, 1, &sts)) < 0) break; if (!rv) continue; if (ev.ident == (guint) up_apm_get_fd() && APM_EVENT_TYPE(ev.data) == APM_POWER_CHANGE ) { /* g_idle_add the callback */ g_idle_add((GSourceFunc) up_backend_apm_powerchange_event_cb, backend); } } return NULL; /* shouldnt be reached ? */ }