From d823aba015768cc857a8ca57db47c264b0868aa8 Mon Sep 17 00:00:00 2001 From: Christopher Michael Date: Mon, 17 May 2010 00:03:55 +0000 Subject: [PATCH] Add a TODO list. Create a device hash to match standard device names to types. Cleanup E_EVENT_ACPI (add missing ones, remove not needed ones). Actually parse out the ACPI data which we receive. You can now actually use this ACPI code for event listening, but the Status field of the event structure needs sanatizing yet (turn into something meaningful). SVN revision: 48928 --- src/bin/e_acpi.c | 160 ++++++++++++++++++++++++++++++++++++++--------- src/bin/e_acpi.h | 14 ++++- 2 files changed, 141 insertions(+), 33 deletions(-) diff --git a/src/bin/e_acpi.c b/src/bin/e_acpi.c index d67fd58d3..7063f8dba 100644 --- a/src/bin/e_acpi.c +++ b/src/bin/e_acpi.c @@ -1,5 +1,24 @@ #include "e.h" +/* TODO: + * + * Sanatize data received from acpi for message status into something + * meaningful (ie: 00000002 == LID_CLOSED, etc, etc). + * + * Find someone with a WIFI that actually emits ACPI events and add/debug the + * E_EVENT_ACPI for wifi. + * + * Add e_actions for bindings. + */ + +/* local structures */ +typedef struct _ACPIDevice ACPIDevice; // for mapping device names to type +struct _ACPIDevice +{ + const char *name; + int type; +}; + /* local function prototypes */ static int _e_acpi_cb_server_del(void *data __UNUSED__, int type __UNUSED__, void *event); static int _e_acpi_cb_server_data(void *data __UNUSED__, int type __UNUSED__, void *event); @@ -8,22 +27,52 @@ static void _e_acpi_cb_event_free(void *data __UNUSED__, void *event); /* local variables */ static Ecore_Con_Server *_e_acpid = NULL; static Eina_List *_e_acpid_hdls = NULL; +static Eina_Hash *_e_acpid_devices = NULL; +static ACPIDevice _devices[] = +{ + /* DO NOT TRANSLATE THESE. */ + /* standardized ACPI device name, corresponding E_ACPI_TYPE */ + {"ac_adapter", E_ACPI_TYPE_AC_ADAPTER}, + {"battery", E_ACPI_TYPE_BATTERY}, + {"button/lid", E_ACPI_TYPE_LID}, + {"button/power", E_ACPI_TYPE_POWER}, + {"button/sleep", E_ACPI_TYPE_SLEEP}, + {"fan", E_ACPI_TYPE_FAN}, + {"processor", E_ACPI_TYPE_PROCESSOR}, + {"thermal_zone", E_ACPI_TYPE_THERMAL}, + {"video", E_ACPI_TYPE_VIDEO}, + {NULL, E_ACPI_TYPE_UNKNOWN} +}; /* public variables */ -EAPI int E_EVENT_ACPI_LID = 0; +EAPI int E_EVENT_ACPI_UNKNOWN = 0; +EAPI int E_EVENT_ACPI_AC_ADAPTER = 0; EAPI int E_EVENT_ACPI_BATTERY = 0; -EAPI int E_EVENT_ACPI_BUTTON = 0; +EAPI int E_EVENT_ACPI_FAN = 0; +EAPI int E_EVENT_ACPI_LID = 0; +EAPI int E_EVENT_ACPI_POWER = 0; +EAPI int E_EVENT_ACPI_PROCESSOR = 0; EAPI int E_EVENT_ACPI_SLEEP = 0; +EAPI int E_EVENT_ACPI_THERMAL = 0; +EAPI int E_EVENT_ACPI_VIDEO = 0; EAPI int E_EVENT_ACPI_WIFI = 0; /* public functions */ EAPI int e_acpi_init(void) { - E_EVENT_ACPI_LID = ecore_event_type_new(); + const ACPIDevice *dev; + + E_EVENT_ACPI_UNKNOWN = ecore_event_type_new(); + E_EVENT_ACPI_AC_ADAPTER = ecore_event_type_new(); E_EVENT_ACPI_BATTERY = ecore_event_type_new(); - E_EVENT_ACPI_BUTTON = ecore_event_type_new(); + E_EVENT_ACPI_FAN = ecore_event_type_new(); + E_EVENT_ACPI_LID = ecore_event_type_new(); + E_EVENT_ACPI_POWER = ecore_event_type_new(); + E_EVENT_ACPI_PROCESSOR = ecore_event_type_new(); E_EVENT_ACPI_SLEEP = ecore_event_type_new(); + E_EVENT_ACPI_THERMAL = ecore_event_type_new(); + E_EVENT_ACPI_VIDEO = ecore_event_type_new(); E_EVENT_ACPI_WIFI = ecore_event_type_new(); /* check for running acpid */ @@ -34,6 +83,11 @@ e_acpi_init(void) "/var/run/acpid.socket", -1, NULL); if (!_e_acpid) return 1; + /* create new device hash and fill it */ + _e_acpid_devices = eina_hash_string_superfast_new(NULL); + for (dev = _devices; dev->type > E_ACPI_TYPE_UNKNOWN; dev++) + eina_hash_direct_add(_e_acpid_devices, dev->name, dev); + /* setup handlers */ _e_acpid_hdls = eina_list_append(_e_acpid_hdls, @@ -51,6 +105,10 @@ e_acpi_shutdown(void) { Ecore_Event_Handler *hdl; + /* destroy the device hash */ + if (_e_acpid_devices) eina_hash_free(_e_acpid_devices); + _e_acpid_devices = NULL; + /* cleanup event handlers */ EINA_LIST_FREE(_e_acpid_hdls, hdl) ecore_event_handler_del(hdl); @@ -85,28 +143,81 @@ static int _e_acpi_cb_server_data(void *data __UNUSED__, int type __UNUSED__, void *event) { Ecore_Con_Event_Server_Data *ev; - int res; + ACPIDevice *dev; + E_Event_Acpi *acpi_event; + int res, sig, status, event_type; + char device[1024], bus[1024]; ev = event; + /* parse out this acpi string into separate pieces */ + if (!(sscanf(ev->data, "%s %4s %8d %8d", device, bus, &sig, &status)) == 4) + return 1; + + /* write out acutal acpi received data to stdout for debugging */ res = fwrite(ev->data, ev->size, 1, stdout); + + printf("Device: %s\n", device); + printf("Bus: %s\n", bus); + printf("Signal: %d\n", sig); + printf("Status: %d\n", status); printf("\n"); - /* TODO: Need to parse this data and raise events according to - * the type of acpi object. See ACPI notes below */ - - /* raise the event - - E_Event_Acpi *acpi_event; - + /* create new event structure to raise */ acpi_event = E_NEW(E_Event_Acpi, 1); - acpi_event->device = eina_stringshare_add("battery"); - acpi_event->bus_id = eina_stringshare_add("BAT0"); - acpi_event->event_type = E_ACPI_BATTERY_STATUS_CHANGED; // make these standard E_ACPI enums - acpi_event->event_data = 1; // change to something more meaningful - ecore_event_add(E_EVENT_ACPI_LID, acpi_event, _e_acpi_cb_event_free, NULL); - */ + acpi_event->bus_id = eina_stringshare_add(bus); + acpi_event->signal = sig; + acpi_event->status = status; + /* determine which device this event is for */ + if ((dev = eina_hash_find(_e_acpid_devices, device))) + { + acpi_event->device = eina_stringshare_add(dev->name); + acpi_event->type = dev->type; + } + else + { + acpi_event->device = eina_stringshare_add("unknown"); + acpi_event->type = E_ACPI_TYPE_UNKNOWN; + } + + /* based on device type, determine the event to raise */ + switch (acpi_event->type) + { + case E_ACPI_TYPE_AC_ADAPTER: + event_type = E_EVENT_ACPI_AC_ADAPTER; + break; + case E_ACPI_TYPE_BATTERY: + event_type = E_EVENT_ACPI_BATTERY; + break; + case E_ACPI_TYPE_FAN: + event_type = E_EVENT_ACPI_FAN; + break; + case E_ACPI_TYPE_LID: + event_type = E_EVENT_ACPI_LID; + break; + case E_ACPI_TYPE_POWER: + event_type = E_EVENT_ACPI_POWER; + break; + case E_ACPI_TYPE_PROCESSOR: + event_type = E_EVENT_ACPI_PROCESSOR; + break; + case E_ACPI_TYPE_SLEEP: + event_type = E_EVENT_ACPI_SLEEP; + break; + case E_ACPI_TYPE_THERMAL: + event_type = E_EVENT_ACPI_THERMAL; + break; + case E_ACPI_TYPE_VIDEO: + event_type = E_EVENT_ACPI_VIDEO; + break; + default: + event_type = E_EVENT_ACPI_UNKNOWN; + break; + } + + /* actually raise the event */ + ecore_event_add(event_type, acpi_event, _e_acpi_cb_event_free, NULL); return 1; } @@ -115,19 +226,8 @@ _e_acpi_cb_event_free(void *data __UNUSED__, void *event) { E_Event_Acpi *ev; + if (!(ev = event)) return; if (ev->device) eina_stringshare_del(ev->device); if (ev->bus_id) eina_stringshare_del(ev->bus_id); E_FREE(ev); } - - -/* ACPI NOTES - * - * http://www.columbia.edu/~ariel/acpi/acpi_howto.txt (Section 6.4) - * - * Typical data looks like: - * completed event "processor CPU0 00000080 00000004" - * received event "ac_adapter AC 00000080 00000001" - * received event "battery BAT0 00000080 00000001" - * received event "button/power PBTN 00000080 00000001" - */ diff --git a/src/bin/e_acpi.h b/src/bin/e_acpi.h index 22fe1b6cf..803c83033 100644 --- a/src/bin/e_acpi.h +++ b/src/bin/e_acpi.h @@ -4,13 +4,14 @@ typedef enum _E_Acpi_Type { E_ACPI_TYPE_UNKNOWN = 0, + E_ACPI_TYPE_AC_ADAPTER, E_ACPI_TYPE_BATTERY, E_ACPI_TYPE_BUTTON, E_ACPI_TYPE_FAN, E_ACPI_TYPE_LID, + E_ACPI_TYPE_POWER, E_ACPI_TYPE_PROCESSOR, E_ACPI_TYPE_SLEEP, - E_ACPI_TYPE_POWER, E_ACPI_TYPE_THERMAL, E_ACPI_TYPE_VIDEO, E_ACPI_TYPE_WIFI @@ -26,16 +27,23 @@ typedef struct _E_Event_Acpi E_Event_Acpi; struct _E_Event_Acpi { const char *device, *bus_id; - int type, data; + int type, signal, status; }; EAPI int e_acpi_init(void); EAPI int e_acpi_shutdown(void); -extern EAPI int E_EVENT_ACPI_LID; +extern EAPI int E_EVENT_ACPI_UNKNOWN; +extern EAPI int E_EVENT_ACPI_AC_ADAPTER; extern EAPI int E_EVENT_ACPI_BATTERY; extern EAPI int E_EVENT_ACPI_BUTTON; +extern EAPI int E_EVENT_ACPI_FAN; +extern EAPI int E_EVENT_ACPI_LID; +extern EAPI int E_EVENT_ACPI_POWER; +extern EAPI int E_EVENT_ACPI_PROCESSOR; extern EAPI int E_EVENT_ACPI_SLEEP; +extern EAPI int E_EVENT_ACPI_THERMAL; +extern EAPI int E_EVENT_ACPI_VIDEO; extern EAPI int E_EVENT_ACPI_WIFI; # endif