a bit of a refactor of e_acpi -> can buffer and handle more than 1

acpi message at once (will happen IF e is paused/hung/suspended and
multiple acpi events happen during that time).

also no need for multiple acpi event id's - the type is already in the
struct itself. it's dup;icating the work. simplify.

also... vaio "hotkey" style support. new mapping ethod needed for
that. who knows what other bizarre acpi hardware is out there. may
need more. also make a note that we may want a mapping system some
time that maps acpi event to faking an x key event.

also... allow acpi bindings to bind to anything in gui.



SVN revision: 56790
This commit is contained in:
Carsten Haitzler 2011-02-07 22:57:50 +00:00
parent fea9dcbda7
commit f8da083328
3 changed files with 188 additions and 195 deletions

View File

@ -11,11 +11,23 @@
*/
/* local structures */
typedef struct _ACPIDevice ACPIDevice; // for mapping device names to type
struct _ACPIDevice
/* for simple acpi device mapping */
typedef struct _E_ACPI_Device_Simple E_ACPI_Device_Simple;
typedef struct _E_ACPI_Device_Multiplexed E_ACPI_Device_Multiplexed;
struct _E_ACPI_Device_Simple
{
const char *name;
int type;
// ->
int type;
};
struct _E_ACPI_Device_Multiplexed
{
const char *name;
int status;
// ->
int type;
};
/* local function prototypes */
@ -29,53 +41,48 @@ static Eina_Bool _e_acpi_cb_event(void *data __UNUSED__, int type __UNUSED__, vo
static int _e_acpi_events_frozen = 0;
static Ecore_Con_Server *_e_acpid = NULL;
static Eina_List *_e_acpid_hdls = NULL;
static Eina_Hash *_e_acpid_devices = NULL;
static ACPIDevice _devices[] =
static Eina_Strbuf *acpibuf = NULL;
static E_ACPI_Device_Simple _devices_simple[] =
{
/* NB: 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},
{"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},
{"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}
{"video", E_ACPI_TYPE_VIDEO},
{NULL, E_ACPI_TYPE_UNKNOWN}
};
static E_ACPI_Device_Multiplexed _devices_multiplexed[] =
{
/* NB: DO NOT TRANSLATE THESE. */
{"sony/hotkey", 0x10, E_ACPI_TYPE_BRIGHTNESS_DOWN},
{"sony/hotkey", 0x11, E_ACPI_TYPE_BRIGHTNESS_UP},
{"sony/hotkey", 0x12, E_ACPI_TYPE_VIDEO},
{"sony/hotkey", 0x14, E_ACPI_TYPE_ZOOM_OUT},
{"sony/hotkey", 0x15, E_ACPI_TYPE_ZOOM_IN},
{"sony/hotkey", 0x17, E_ACPI_TYPE_HIBERNATE},
{"sony/hotkey", 0xa6, E_ACPI_TYPE_ASSIST},
{"sony/hotkey", 0x20, E_ACPI_TYPE_S1},
{"sony/hotkey", 0xa5, E_ACPI_TYPE_VAIO},
{NULL, 0x00, E_ACPI_TYPE_UNKNOWN}
};
/* public variables */
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_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;
EAPI int E_EVENT_ACPI = 0;
/* public functions */
EINTERN int
e_acpi_init(void)
{
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_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();
E_EVENT_ACPI = ecore_event_type_new();
/* check for running acpid */
if (!ecore_file_exists("/var/run/acpid.socket")) return 1;
@ -85,38 +92,21 @@ 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,
ecore_event_handler_add(ECORE_CON_EVENT_SERVER_DEL,
_e_acpi_cb_server_del, NULL));
eina_list_append(_e_acpid_hdls,
ecore_event_handler_add(ECORE_CON_EVENT_SERVER_DEL,
_e_acpi_cb_server_del, NULL));
_e_acpid_hdls =
eina_list_append(_e_acpid_hdls,
ecore_event_handler_add(ECORE_CON_EVENT_SERVER_DATA,
_e_acpi_cb_server_data, NULL));
eina_list_append(_e_acpid_hdls,
ecore_event_handler_add(ECORE_CON_EVENT_SERVER_DATA,
_e_acpi_cb_server_data, NULL));
/* Add handlers for standard acpi events */
_e_acpid_hdls =
eina_list_append(_e_acpid_hdls,
ecore_event_handler_add(E_EVENT_ACPI_AC_ADAPTER,
_e_acpi_cb_event, NULL));
_e_acpid_hdls =
eina_list_append(_e_acpid_hdls,
ecore_event_handler_add(E_EVENT_ACPI_LID,
_e_acpi_cb_event, NULL));
_e_acpid_hdls =
eina_list_append(_e_acpid_hdls,
ecore_event_handler_add(E_EVENT_ACPI_POWER,
_e_acpi_cb_event, NULL));
_e_acpid_hdls =
eina_list_append(_e_acpid_hdls,
ecore_event_handler_add(E_EVENT_ACPI_SLEEP,
_e_acpi_cb_event, NULL));
eina_list_append(_e_acpid_hdls,
ecore_event_handler_add(E_EVENT_ACPI,
_e_acpi_cb_event, NULL));
return 1;
}
@ -125,17 +115,15 @@ 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);
EINA_LIST_FREE(_e_acpid_hdls, hdl) ecore_event_handler_del(hdl);
/* kill the server if existing */
if (_e_acpid) ecore_con_server_del(_e_acpid);
_e_acpid = NULL;
if (_e_acpid)
{
ecore_con_server_del(_e_acpid);
_e_acpid = NULL;
}
return 1;
}
@ -163,12 +151,14 @@ _e_acpi_cb_server_del(void *data __UNUSED__, int type __UNUSED__, void *event)
if (ev->server != _e_acpid) return ECORE_CALLBACK_PASS_ON;
/* cleanup event handlers */
EINA_LIST_FREE(_e_acpid_hdls, hdl)
ecore_event_handler_del(hdl);
EINA_LIST_FREE(_e_acpid_hdls, hdl) ecore_event_handler_del(hdl);
/* kill the server if existing */
if (_e_acpid) ecore_con_server_del(_e_acpid);
_e_acpid = NULL;
if (_e_acpid)
{
ecore_con_server_del(_e_acpid);
_e_acpid = NULL;
}
return ECORE_CALLBACK_PASS_ON;
}
@ -176,12 +166,11 @@ static Eina_Bool
_e_acpi_cb_server_data(void *data __UNUSED__, int type __UNUSED__, void *event)
{
Ecore_Con_Event_Server_Data *ev;
ACPIDevice *dev;
E_Event_Acpi *acpi_event;
int sig, status, event_type;
char device[1024], bus[1024];
char *sdata;
int sig, status, i, done = 0;
char device[1024], bus[1024], *sdata;
const char *str, *p;
ev = event;
/* write out actual acpi received data to stdout for debugging
@ -190,70 +179,90 @@ _e_acpi_cb_server_data(void *data __UNUSED__, int type __UNUSED__, void *event)
/* data from a server isnt a string - its not 0 byte terminated. it's just
* a blob of data. copy to string and 0 byte terminate it so it can be
* string-swizzled/parsed etc. */
sdata = alloca(ev->size + 1);
memcpy(sdata, ev->data, ev->size);
sdata[ev->size] = 0;
/* parse out this acpi string into separate pieces */
if (sscanf(sdata, "%s %s %d %d", device, bus, &sig, &status) != 4)
return ECORE_CALLBACK_PASS_ON;
/* create new event structure to raise */
acpi_event = E_NEW(E_Event_Acpi, 1);
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)))
if (!acpibuf) acpibuf = eina_strbuf_new();
eina_strbuf_append_n(acpibuf, ev->data, ev->size);
str = eina_strbuf_string_get(acpibuf);
p = strchr(str, '\n');
if (!p) return ECORE_CALLBACK_PASS_ON;
while (p)
{
acpi_event->device = eina_stringshare_add(dev->name);
acpi_event->type = dev->type;
sdata = alloca(p - str + 1);
strncpy(sdata, str, (int)(p - str));
sdata[p - str] = 0;
/* parse out this acpi string into separate pieces */
if (sscanf(sdata, "%1023s %1023s %x %x",
device, bus, &sig, &status) == 4)
{
/* create new event structure to raise */
acpi_event = E_NEW(E_Event_Acpi, 1);
acpi_event->bus_id = eina_stringshare_add(bus);
acpi_event->signal = sig;
acpi_event->status = status;
/* FIXME: add in a key faking layer */
if (!done)
{
for (i = 0; _devices_multiplexed[i].name; i++)
{
if ((!strcmp(device, _devices_multiplexed[i].name)) &&
(_devices_multiplexed[i].status == status))
{
acpi_event->type = _devices_multiplexed[i].type;
done = 1;
break;
}
}
}
if (!done)
{
for (i = 0; _devices_simple[i].name; i++)
{
if (!strcmp(device, _devices_simple[i].name))
{
acpi_event->type = _devices_simple[i].type;
done = 1;
break;
}
}
}
if (!done)
{
free(acpi_event);
acpi_event = NULL;
}
else
{
switch (acpi_event->type)
{
case E_ACPI_TYPE_LID:
acpi_event->status =
_e_acpi_lid_status_get(device, bus);
break;
default:
break;
}
/* actually raise the event */
ecore_event_add(E_EVENT_ACPI, acpi_event,
_e_acpi_cb_event_free, NULL);
}
}
str = p + 1;
p = strchr(str, '\n');
}
else
if (str[0] == 0)
{
acpi_event->device = eina_stringshare_add(device);
acpi_event->type = E_ACPI_TYPE_UNKNOWN;
eina_strbuf_free(acpibuf);
acpibuf = NULL;
}
/* based on device type, determine the event to raise */
switch (acpi_event->type)
else
{
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;
acpi_event->status =
_e_acpi_lid_status_get(acpi_event->device, acpi_event->bus_id);
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;
Eina_Strbuf *newbuf;
newbuf = eina_strbuf_new();
eina_strbuf_append(newbuf, str);
eina_strbuf_free(acpibuf);
acpibuf = newbuf;
}
/* actually raise the event */
ecore_event_add(event_type, acpi_event, _e_acpi_cb_event_free, NULL);
return ECORE_CALLBACK_PASS_ON;
}
@ -297,12 +306,9 @@ _e_acpi_lid_status_get(const char *device, const char *bus)
while (!isalnum(buff[i])) i++;
/* compare value from state file and return something sane */
if (!strcmp(buff, "open"))
return E_ACPI_LID_OPEN;
else if (!strcmp(buff, "closed"))
return E_ACPI_LID_CLOSED;
else
return E_ACPI_LID_UNKNOWN;
if (!strcmp(buff, "open")) return E_ACPI_LID_OPEN;
else if (!strcmp(buff, "closed")) return E_ACPI_LID_CLOSED;
else return E_ACPI_LID_UNKNOWN;
}
static Eina_Bool

View File

@ -4,7 +4,8 @@
typedef enum _E_Acpi_Type
{
E_ACPI_TYPE_UNKNOWN = 0,
E_ACPI_TYPE_AC_ADAPTER,
E_ACPI_TYPE_AC_ADAPTER, //
E_ACPI_TYPE_BATTERY,
E_ACPI_TYPE_BUTTON,
E_ACPI_TYPE_FAN,
@ -14,7 +15,15 @@ typedef enum _E_Acpi_Type
E_ACPI_TYPE_SLEEP,
E_ACPI_TYPE_THERMAL,
E_ACPI_TYPE_VIDEO,
E_ACPI_TYPE_WIFI
E_ACPI_TYPE_WIFI,
E_ACPI_TYPE_HIBERNATE,
E_ACPI_TYPE_ZOOM_OUT,
E_ACPI_TYPE_ZOOM_IN,
E_ACPI_TYPE_BRIGHTNESS_DOWN,
E_ACPI_TYPE_BRIGHTNESS_UP,
E_ACPI_TYPE_ASSIST,
E_ACPI_TYPE_S1,
E_ACPI_TYPE_VAIO
} E_Acpi_Type;
/* enum for acpi signals */
@ -45,26 +54,16 @@ typedef struct _E_Event_Acpi E_Event_Acpi;
struct _E_Event_Acpi
{
const char *device, *bus_id;
int type, signal, status;
int type, signal, status;
};
EINTERN int e_acpi_init(void);
EINTERN int e_acpi_shutdown(void);
EAPI void e_acpi_events_freeze(void);
EAPI void e_acpi_events_thaw(void);
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;
extern EAPI int E_EVENT_ACPI;
# endif
#endif

View File

@ -278,9 +278,9 @@ _fill_actions(E_Config_Dialog_Data *cfdata)
EINA_LIST_FOREACH(e_action_groups_get(), l, grp)
{
if (!grp->acts) continue;
if ((strcmp(grp->act_grp, "Acpi")) &&
(strcmp(grp->act_grp, "System")) &&
(strcmp(grp->act_grp, "Launch"))) continue;
// if ((strcmp(grp->act_grp, "Acpi")) &&
// (strcmp(grp->act_grp, "System")) &&
// (strcmp(grp->act_grp, "Launch"))) continue;
e_widget_ilist_header_append(cfdata->o_actions, NULL, _(grp->act_grp));
EINA_LIST_FOREACH(grp->acts, ll, dsc)
e_widget_ilist_append(cfdata->o_actions, NULL, _(dsc->act_name),
@ -325,9 +325,9 @@ _selected_action_get(E_Config_Dialog_Data *cfdata)
EINA_LIST_FOREACH(e_action_groups_get(), l, grp)
{
if (!grp->acts) continue;
if ((strcmp(grp->act_grp, "Acpi")) &&
(strcmp(grp->act_grp, "System")) &&
(strcmp(grp->act_grp, "Launch"))) continue;
// if ((strcmp(grp->act_grp, "Acpi")) &&
// (strcmp(grp->act_grp, "System")) &&
// (strcmp(grp->act_grp, "Launch"))) continue;
EINA_LIST_FOREACH(grp->acts, ll, dsc)
{
if ((dsc->act_name) && (!strcmp(dsc->act_name, lbl)))
@ -372,6 +372,22 @@ _binding_label_get(E_Config_Binding_Acpi *bind)
return _("Video");
if (bind->type == E_ACPI_TYPE_WIFI)
return _("Wifi");
if (bind->type == E_ACPI_TYPE_HIBERNATE)
return _("Hibernate");
if (bind->type == E_ACPI_TYPE_ZOOM_OUT)
return _("Zoom Out");
if (bind->type == E_ACPI_TYPE_ZOOM_IN)
return _("Zoom In");
if (bind->type == E_ACPI_TYPE_BRIGHTNESS_DOWN)
return _("Brightness Down");
if (bind->type == E_ACPI_TYPE_BRIGHTNESS_UP)
return _("Brightness Up");
if (bind->type == E_ACPI_TYPE_ASSIST)
return _("Assist");
if (bind->type == E_ACPI_TYPE_S1)
return _("S1");
if (bind->type == E_ACPI_TYPE_VAIO)
return _("Vaio");
return NULL;
}
@ -493,35 +509,7 @@ _cb_add_binding(void *data,
_cb_grab_key_down, cfdata));
grab_hdls =
eina_list_append(grab_hdls,
ecore_event_handler_add(E_EVENT_ACPI_AC_ADAPTER,
_cb_acpi_event, cfdata));
grab_hdls =
eina_list_append(grab_hdls,
ecore_event_handler_add(E_EVENT_ACPI_BATTERY,
_cb_acpi_event, cfdata));
grab_hdls =
eina_list_append(grab_hdls,
ecore_event_handler_add(E_EVENT_ACPI_FAN,
_cb_acpi_event, cfdata));
grab_hdls =
eina_list_append(grab_hdls,
ecore_event_handler_add(E_EVENT_ACPI_LID,
_cb_acpi_event, cfdata));
grab_hdls =
eina_list_append(grab_hdls,
ecore_event_handler_add(E_EVENT_ACPI_POWER,
_cb_acpi_event, cfdata));
grab_hdls =
eina_list_append(grab_hdls,
ecore_event_handler_add(E_EVENT_ACPI_SLEEP,
_cb_acpi_event, cfdata));
grab_hdls =
eina_list_append(grab_hdls,
ecore_event_handler_add(E_EVENT_ACPI_VIDEO,
_cb_acpi_event, cfdata));
grab_hdls =
eina_list_append(grab_hdls,
ecore_event_handler_add(E_EVENT_ACPI_WIFI,
ecore_event_handler_add(E_EVENT_ACPI,
_cb_acpi_event, cfdata));
/* freeze all incoming acpi events */