logind: allow binding different operation to reboot key long presses

This commit is contained in:
Yegor Alexeyev 2021-06-12 01:18:07 +03:00 committed by Lennart Poettering
parent 949162552d
commit a520bb6654
8 changed files with 198 additions and 33 deletions

View file

@ -194,12 +194,16 @@
<varlistentry> <varlistentry>
<term><varname>HandlePowerKey=</varname></term> <term><varname>HandlePowerKey=</varname></term>
<term><varname>HandlePowerKeyLongPress=</varname></term>
<term><varname>HandleRebootKey=</varname></term>
<term><varname>HandleRebootKeyLongPress=</varname></term>
<term><varname>HandleSuspendKey=</varname></term> <term><varname>HandleSuspendKey=</varname></term>
<term><varname>HandleSuspendKeyLongPress=</varname></term>
<term><varname>HandleHibernateKey=</varname></term> <term><varname>HandleHibernateKey=</varname></term>
<term><varname>HandleHibernateKeyLongPress=</varname></term>
<term><varname>HandleLidSwitch=</varname></term> <term><varname>HandleLidSwitch=</varname></term>
<term><varname>HandleLidSwitchExternalPower=</varname></term> <term><varname>HandleLidSwitchExternalPower=</varname></term>
<term><varname>HandleLidSwitchDocked=</varname></term> <term><varname>HandleLidSwitchDocked=</varname></term>
<term><varname>HandleRebootKey=</varname></term>
<listitem><para>Controls how logind shall handle the <listitem><para>Controls how logind shall handle the
system power, reboot and sleep keys and the lid switch to trigger system power, reboot and sleep keys and the lid switch to trigger
@ -221,17 +225,20 @@
<literal>power-switch</literal> udev tag will be watched for <literal>power-switch</literal> udev tag will be watched for
key/lid switch events. <varname>HandlePowerKey=</varname> key/lid switch events. <varname>HandlePowerKey=</varname>
defaults to <literal>poweroff</literal>, <varname>HandleRebootKey=</varname> defaults to <literal>poweroff</literal>, <varname>HandleRebootKey=</varname>
defaults to <literal>reboot</literal>. defaults to <literal>reboot</literal>, <varname>HandleSuspendKey=</varname>
<varname>HandleSuspendKey=</varname> and defaults to <literal>suspend</literal>, <varname>HandleHibernateKey=</varname>
<varname>HandleLidSwitch=</varname> default to defaults to <literal>hibernate</literal>, <varname>HandlePowerKeyLongPress=</varname>
defaults to <literal>ignore</literal>, <varname>HandleRebootKeyLongPress=</varname>
defaults to <literal>poweroff</literal>, <varname>HandleSuspendKeyLongPress=</varname>
defaults to <literal>hibernate</literal>, <varname>HandleHibernateKeyLongPress=</varname>
defaults to <literal>ignore</literal>.
<varname>HandleLidSwitch=</varname> defaults to
<literal>suspend</literal>. <literal>suspend</literal>.
<varname>HandleLidSwitchExternalPower=</varname> is completely <varname>HandleLidSwitchExternalPower=</varname> is completely
ignored by default (for backwards compatibility) — an explicit ignored by default (for backwards compatibility) — an explicit
value must be set before it will be used to determine value must be set before it will be used to determine
behaviour. <varname>HandleLidSwitchDocked=</varname> defaults behaviour. <varname>HandleLidSwitchDocked=</varname> defaults
to <literal>ignore</literal>. to <literal>ignore</literal>. If the system is inserted in a
<varname>HandleHibernateKey=</varname> defaults to
<literal>hibernate</literal>. If the system is inserted in a
docking station, or if more than one display is connected, the docking station, or if more than one display is connected, the
action specified by <varname>HandleLidSwitchDocked=</varname> action specified by <varname>HandleLidSwitchDocked=</varname>
occurs; if the system is on external power the action (if any) occurs; if the system is on external power the action (if any)
@ -243,7 +250,7 @@
sleep keys and the lid switch by taking a low-level inhibitor lock sleep keys and the lid switch by taking a low-level inhibitor lock
(<literal>handle-power-key</literal>, <literal>handle-suspend-key</literal>, (<literal>handle-power-key</literal>, <literal>handle-suspend-key</literal>,
<literal>handle-hibernate-key</literal>, <literal>handle-lid-switch</literal>, <literal>handle-hibernate-key</literal>, <literal>handle-lid-switch</literal>,
<literal>handle-reboot-switch</literal>). <literal>handle-reboot-key</literal>).
This is most commonly used by graphical desktop environments This is most commonly used by graphical desktop environments
to take over suspend and hibernation handling, and to use their own configuration to take over suspend and hibernation handling, and to use their own configuration
mechanisms. If a low-level inhibitor lock is taken, logind will not take any mechanisms. If a low-level inhibitor lock is taken, logind will not take any

View file

@ -19,6 +19,8 @@
#define ULONG_BITS (sizeof(unsigned long)*8) #define ULONG_BITS (sizeof(unsigned long)*8)
#define LONG_PRESS_DURATION (5 * USEC_PER_SEC)
static bool bitset_get(const unsigned long *bits, unsigned i) { static bool bitset_get(const unsigned long *bits, unsigned i) {
return (bits[i / ULONG_BITS] >> (i % ULONG_BITS)) & 1UL; return (bits[i / ULONG_BITS] >> (i % ULONG_BITS)) & 1UL;
} }
@ -117,6 +119,89 @@ static int button_install_check_event_source(Button *b) {
return sd_event_source_set_priority(b->check_event_source, SD_EVENT_PRIORITY_IDLE+1); return sd_event_source_set_priority(b->check_event_source, SD_EVENT_PRIORITY_IDLE+1);
} }
static int long_press_of_power_key_handler(sd_event_source *e, uint64_t usec, void *userdata) {
Manager *m = userdata;
assert(e);
assert(m);
m->power_key_long_press_event_source = sd_event_source_unref(m->power_key_long_press_event_source);
log_struct(LOG_INFO,
LOG_MESSAGE("Power key pressed long."),
"MESSAGE_ID=" SD_MESSAGE_POWER_KEY_LONG_PRESS_STR);
manager_handle_action(m, INHIBIT_HANDLE_POWER_KEY, m->handle_power_key_long_press, m->power_key_ignore_inhibited, true);
return 0;
}
static int long_press_of_reboot_key_handler(sd_event_source *e, uint64_t usec, void *userdata) {
Manager *m = userdata;
assert(e);
assert(m);
m->reboot_key_long_press_event_source = sd_event_source_unref(m->reboot_key_long_press_event_source);
log_struct(LOG_INFO,
LOG_MESSAGE("Reboot key pressed long."),
"MESSAGE_ID=" SD_MESSAGE_REBOOT_KEY_LONG_PRESS_STR);
manager_handle_action(m, INHIBIT_HANDLE_REBOOT_KEY, m->handle_reboot_key_long_press, m->reboot_key_ignore_inhibited, true);
return 0;
}
static int long_press_of_suspend_key_handler(sd_event_source *e, uint64_t usec, void *userdata) {
Manager *m = userdata;
assert(e);
assert(m);
m->suspend_key_long_press_event_source = sd_event_source_unref(m->suspend_key_long_press_event_source);
log_struct(LOG_INFO,
LOG_MESSAGE("Suspend key pressed long."),
"MESSAGE_ID=" SD_MESSAGE_SUSPEND_KEY_LONG_PRESS_STR);
manager_handle_action(m, INHIBIT_HANDLE_SUSPEND_KEY, m->handle_suspend_key_long_press, m->suspend_key_ignore_inhibited, true);
return 0;
}
static int long_press_of_hibernate_key_handler(sd_event_source *e, uint64_t usec, void *userdata) {
Manager *m = userdata;
assert(e);
assert(m);
m->hibernate_key_long_press_event_source = sd_event_source_unref(m->hibernate_key_long_press_event_source);
log_struct(LOG_INFO,
LOG_MESSAGE("Hibernate key pressed long."),
"MESSAGE_ID=" SD_MESSAGE_HIBERNATE_KEY_LONG_PRESS_STR);
manager_handle_action(m, INHIBIT_HANDLE_HIBERNATE_KEY, m->handle_hibernate_key_long_press, m->hibernate_key_ignore_inhibited, true);
return 0;
}
static void start_long_press(Manager *m, sd_event_source **e, sd_event_time_handler_t callback) {
int r;
assert(m);
assert(e);
if (*e)
return;
r = sd_event_add_time_relative(
m->event,
e,
CLOCK_MONOTONIC,
LONG_PRESS_DURATION, 0,
callback, m);
if (r < 0)
log_warning_errno(r, "Failed to add long press timer event, ignoring: %m");
}
static int button_dispatch(sd_event_source *s, int fd, uint32_t revents, void *userdata) { static int button_dispatch(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
Button *b = userdata; Button *b = userdata;
struct input_event ev; struct input_event ev;
@ -138,11 +223,14 @@ static int button_dispatch(sd_event_source *s, int fd, uint32_t revents, void *u
case KEY_POWER: case KEY_POWER:
case KEY_POWER2: case KEY_POWER2:
log_struct(LOG_INFO, if (b->manager->handle_power_key_long_press != HANDLE_IGNORE && b->manager->handle_power_key_long_press != b->manager->handle_power_key) {
LOG_MESSAGE("Power key pressed."), log_debug("Power key pressed. Further action depends on the key press duration.");
"MESSAGE_ID=" SD_MESSAGE_POWER_KEY_STR); start_long_press(b->manager, &b->manager->power_key_long_press_event_source, long_press_of_power_key_handler);
} else {
manager_handle_action(b->manager, INHIBIT_HANDLE_POWER_KEY, b->manager->handle_power_key, b->manager->power_key_ignore_inhibited, true); log_struct(LOG_INFO, LOG_MESSAGE("Power key pressed short."),
"MESSAGE_ID=" SD_MESSAGE_POWER_KEY_STR);
manager_handle_action(b->manager, INHIBIT_HANDLE_POWER_KEY, b->manager->handle_power_key, b->manager->power_key_ignore_inhibited, true);
}
break; break;
/* The kernel naming is a bit confusing here: /* The kernel naming is a bit confusing here:
@ -151,11 +239,14 @@ static int button_dispatch(sd_event_source *s, int fd, uint32_t revents, void *u
*/ */
case KEY_RESTART: case KEY_RESTART:
log_struct(LOG_INFO, if (b->manager->handle_reboot_key_long_press != HANDLE_IGNORE && b->manager->handle_reboot_key_long_press != b->manager->handle_reboot_key) {
LOG_MESSAGE("Reboot key pressed."), log_debug("Reboot key pressed. Further action depends on the key press duration.");
"MESSAGE_ID=" SD_MESSAGE_REBOOT_KEY_STR); start_long_press(b->manager, &b->manager->reboot_key_long_press_event_source, long_press_of_reboot_key_handler);
} else {
manager_handle_action(b->manager, INHIBIT_HANDLE_REBOOT_KEY, b->manager->handle_reboot_key, b->manager->reboot_key_ignore_inhibited, true); log_struct(LOG_INFO, LOG_MESSAGE("Reboot key pressed short."),
"MESSAGE_ID=" SD_MESSAGE_REBOOT_KEY_STR);
manager_handle_action(b->manager, INHIBIT_HANDLE_REBOOT_KEY, b->manager->handle_reboot_key, b->manager->reboot_key_ignore_inhibited, true);
}
break; break;
/* The kernel naming is a bit confusing here: /* The kernel naming is a bit confusing here:
@ -165,22 +256,45 @@ static int button_dispatch(sd_event_source *s, int fd, uint32_t revents, void *u
*/ */
case KEY_SLEEP: case KEY_SLEEP:
log_struct(LOG_INFO, if (b->manager->handle_suspend_key_long_press != HANDLE_IGNORE && b->manager->handle_suspend_key_long_press != b->manager->handle_suspend_key) {
LOG_MESSAGE("Suspend key pressed."), log_debug("Suspend key pressed. Further action depends on the key press duration.");
"MESSAGE_ID=" SD_MESSAGE_SUSPEND_KEY_STR); start_long_press(b->manager, &b->manager->suspend_key_long_press_event_source, long_press_of_suspend_key_handler);
} else {
manager_handle_action(b->manager, INHIBIT_HANDLE_SUSPEND_KEY, b->manager->handle_suspend_key, b->manager->suspend_key_ignore_inhibited, true); log_struct(LOG_INFO, LOG_MESSAGE("Suspend key pressed short."),
"MESSAGE_ID=" SD_MESSAGE_SUSPEND_KEY_STR);
manager_handle_action(b->manager, INHIBIT_HANDLE_SUSPEND_KEY, b->manager->handle_suspend_key, b->manager->suspend_key_ignore_inhibited, true);
}
break; break;
case KEY_SUSPEND: case KEY_SUSPEND:
log_struct(LOG_INFO, if (b->manager->handle_hibernate_key_long_press != HANDLE_IGNORE && b->manager->handle_hibernate_key_long_press != b->manager->handle_hibernate_key) {
LOG_MESSAGE("Hibernate key pressed."), log_debug("Hibernate key pressed. Further action depends on the key press duration.");
"MESSAGE_ID=" SD_MESSAGE_HIBERNATE_KEY_STR); start_long_press(b->manager, &b->manager->hibernate_key_long_press_event_source, long_press_of_hibernate_key_handler);
} else {
manager_handle_action(b->manager, INHIBIT_HANDLE_HIBERNATE_KEY, b->manager->handle_hibernate_key, b->manager->hibernate_key_ignore_inhibited, true); log_struct(LOG_INFO, LOG_MESSAGE("Hibernate key pressed short."),
"MESSAGE_ID=" SD_MESSAGE_HIBERNATE_KEY_STR);
manager_handle_action(b->manager, INHIBIT_HANDLE_HIBERNATE_KEY, b->manager->handle_hibernate_key, b->manager->hibernate_key_ignore_inhibited, true);
}
break; break;
} }
} else if (ev.type == EV_KEY && ev.value == 0) {
if (ev.code == KEY_RESTART) {
if (b->manager->reboot_key_long_press_event_source) {
/* Long press event timer is still pending and key release
event happened. This means that key press duration was
insufficient to trigger a long press event
*/
log_struct(LOG_INFO,
LOG_MESSAGE("Reboot key pressed short."),
"MESSAGE_ID=" SD_MESSAGE_REBOOT_KEY_STR);
b->manager->reboot_key_long_press_event_source = sd_event_source_unref(b->manager->reboot_key_long_press_event_source);
manager_handle_action(b->manager, INHIBIT_HANDLE_REBOOT_KEY, b->manager->handle_reboot_key, b->manager->reboot_key_ignore_inhibited, true);
}
}
} else if (ev.type == EV_SW && ev.value > 0) { } else if (ev.type == EV_SW && ev.value > 0) {
if (ev.code == SW_LID) { if (ev.code == SW_LID) {

View file

@ -39,12 +39,18 @@ void manager_reset_config(Manager *m) {
m->user_stop_delay = 10 * USEC_PER_SEC; m->user_stop_delay = 10 * USEC_PER_SEC;
m->handle_power_key = HANDLE_POWEROFF; m->handle_power_key = HANDLE_POWEROFF;
m->handle_power_key_long_press = HANDLE_IGNORE;
m->handle_reboot_key = HANDLE_REBOOT;
m->handle_reboot_key_long_press = HANDLE_POWEROFF;
m->handle_suspend_key = HANDLE_SUSPEND; m->handle_suspend_key = HANDLE_SUSPEND;
m->handle_suspend_key_long_press = HANDLE_HIBERNATE;
m->handle_hibernate_key = HANDLE_HIBERNATE; m->handle_hibernate_key = HANDLE_HIBERNATE;
m->handle_hibernate_key_long_press = HANDLE_IGNORE;
m->handle_lid_switch = HANDLE_SUSPEND; m->handle_lid_switch = HANDLE_SUSPEND;
m->handle_lid_switch_ep = _HANDLE_ACTION_INVALID; m->handle_lid_switch_ep = _HANDLE_ACTION_INVALID;
m->handle_lid_switch_docked = HANDLE_IGNORE; m->handle_lid_switch_docked = HANDLE_IGNORE;
m->handle_reboot_key = HANDLE_REBOOT;
m->power_key_ignore_inhibited = false; m->power_key_ignore_inhibited = false;
m->suspend_key_ignore_inhibited = false; m->suspend_key_ignore_inhibited = false;
m->hibernate_key_ignore_inhibited = false; m->hibernate_key_ignore_inhibited = false;
@ -670,18 +676,26 @@ bool manager_all_buttons_ignored(Manager *m) {
if (m->handle_power_key != HANDLE_IGNORE) if (m->handle_power_key != HANDLE_IGNORE)
return false; return false;
if (m->handle_power_key_long_press != HANDLE_IGNORE)
return false;
if (m->handle_suspend_key != HANDLE_IGNORE) if (m->handle_suspend_key != HANDLE_IGNORE)
return false; return false;
if (m->handle_suspend_key_long_press != HANDLE_IGNORE)
return false;
if (m->handle_hibernate_key != HANDLE_IGNORE) if (m->handle_hibernate_key != HANDLE_IGNORE)
return false; return false;
if (m->handle_hibernate_key_long_press != HANDLE_IGNORE)
return false;
if (m->handle_reboot_key != HANDLE_IGNORE)
return false;
if (m->handle_reboot_key_long_press != HANDLE_IGNORE)
return false;
if (m->handle_lid_switch != HANDLE_IGNORE) if (m->handle_lid_switch != HANDLE_IGNORE)
return false; return false;
if (!IN_SET(m->handle_lid_switch_ep, _HANDLE_ACTION_INVALID, HANDLE_IGNORE)) if (!IN_SET(m->handle_lid_switch_ep, _HANDLE_ACTION_INVALID, HANDLE_IGNORE))
return false; return false;
if (m->handle_lid_switch_docked != HANDLE_IGNORE) if (m->handle_lid_switch_docked != HANDLE_IGNORE)
return false; return false;
if (m->handle_reboot_key != HANDLE_IGNORE)
return false;
return true; return true;
} }

View file

@ -26,12 +26,16 @@ Login.KillExcludeUsers, config_parse_strv, 0, offse
Login.InhibitDelayMaxSec, config_parse_sec, 0, offsetof(Manager, inhibit_delay_max) Login.InhibitDelayMaxSec, config_parse_sec, 0, offsetof(Manager, inhibit_delay_max)
Login.UserStopDelaySec, config_parse_sec, 0, offsetof(Manager, user_stop_delay) Login.UserStopDelaySec, config_parse_sec, 0, offsetof(Manager, user_stop_delay)
Login.HandlePowerKey, config_parse_handle_action, 0, offsetof(Manager, handle_power_key) Login.HandlePowerKey, config_parse_handle_action, 0, offsetof(Manager, handle_power_key)
Login.HandlePowerKeyLongPress, config_parse_handle_action, 0, offsetof(Manager, handle_power_key_long_press)
Login.HandleRebootKey, config_parse_handle_action, 0, offsetof(Manager, handle_reboot_key)
Login.HandleRebootKeyLongPress, config_parse_handle_action, 0, offsetof(Manager, handle_reboot_key_long_press)
Login.HandleSuspendKey, config_parse_handle_action, 0, offsetof(Manager, handle_suspend_key) Login.HandleSuspendKey, config_parse_handle_action, 0, offsetof(Manager, handle_suspend_key)
Login.HandleSuspendKeyLongPress, config_parse_handle_action, 0, offsetof(Manager, handle_suspend_key_long_press)
Login.HandleHibernateKey, config_parse_handle_action, 0, offsetof(Manager, handle_hibernate_key) Login.HandleHibernateKey, config_parse_handle_action, 0, offsetof(Manager, handle_hibernate_key)
Login.HandleHibernateKeyLongPress, config_parse_handle_action, 0, offsetof(Manager, handle_hibernate_key_long_press)
Login.HandleLidSwitch, config_parse_handle_action, 0, offsetof(Manager, handle_lid_switch) Login.HandleLidSwitch, config_parse_handle_action, 0, offsetof(Manager, handle_lid_switch)
Login.HandleLidSwitchExternalPower, config_parse_handle_action, 0, offsetof(Manager, handle_lid_switch_ep) Login.HandleLidSwitchExternalPower, config_parse_handle_action, 0, offsetof(Manager, handle_lid_switch_ep)
Login.HandleLidSwitchDocked, config_parse_handle_action, 0, offsetof(Manager, handle_lid_switch_docked) Login.HandleLidSwitchDocked, config_parse_handle_action, 0, offsetof(Manager, handle_lid_switch_docked)
Login.HandleRebootKey, config_parse_handle_action, 0, offsetof(Manager, handle_reboot_key)
Login.PowerKeyIgnoreInhibited, config_parse_bool, 0, offsetof(Manager, power_key_ignore_inhibited) Login.PowerKeyIgnoreInhibited, config_parse_bool, 0, offsetof(Manager, power_key_ignore_inhibited)
Login.SuspendKeyIgnoreInhibited, config_parse_bool, 0, offsetof(Manager, suspend_key_ignore_inhibited) Login.SuspendKeyIgnoreInhibited, config_parse_bool, 0, offsetof(Manager, suspend_key_ignore_inhibited)
Login.HibernateKeyIgnoreInhibited, config_parse_bool, 0, offsetof(Manager, hibernate_key_ignore_inhibited) Login.HibernateKeyIgnoreInhibited, config_parse_bool, 0, offsetof(Manager, hibernate_key_ignore_inhibited)

View file

@ -140,6 +140,8 @@ static Manager* manager_unref(Manager *m) {
sd_event_source_unref(m->console_active_event_source); sd_event_source_unref(m->console_active_event_source);
sd_event_source_unref(m->lid_switch_ignore_event_source); sd_event_source_unref(m->lid_switch_ignore_event_source);
sd_event_source_unref(m->reboot_key_long_press_event_source);
#if ENABLE_UTMP #if ENABLE_UTMP
sd_event_source_unref(m->utmp_event_source); sd_event_source_unref(m->utmp_event_source);
#endif #endif

View file

@ -29,6 +29,7 @@
#HandleLidSwitchExternalPower=suspend #HandleLidSwitchExternalPower=suspend
#HandleLidSwitchDocked=ignore #HandleLidSwitchDocked=ignore
#HandleRebootKey=reboot #HandleRebootKey=reboot
#HandleRebootKeyLongPress=poweroff
#PowerKeyIgnoreInhibited=no #PowerKeyIgnoreInhibited=no
#SuspendKeyIgnoreInhibited=no #SuspendKeyIgnoreInhibited=no
#HibernateKeyIgnoreInhibited=no #HibernateKeyIgnoreInhibited=no

View file

@ -102,12 +102,17 @@ struct Manager {
HandleAction idle_action; HandleAction idle_action;
HandleAction handle_power_key; HandleAction handle_power_key;
HandleAction handle_power_key_long_press;
HandleAction handle_reboot_key;
HandleAction handle_reboot_key_long_press;
HandleAction handle_suspend_key; HandleAction handle_suspend_key;
HandleAction handle_suspend_key_long_press;
HandleAction handle_hibernate_key; HandleAction handle_hibernate_key;
HandleAction handle_hibernate_key_long_press;
HandleAction handle_lid_switch; HandleAction handle_lid_switch;
HandleAction handle_lid_switch_ep; HandleAction handle_lid_switch_ep;
HandleAction handle_lid_switch_docked; HandleAction handle_lid_switch_docked;
HandleAction handle_reboot_key;
bool power_key_ignore_inhibited; bool power_key_ignore_inhibited;
bool suspend_key_ignore_inhibited; bool suspend_key_ignore_inhibited;
@ -122,6 +127,11 @@ struct Manager {
usec_t holdoff_timeout_usec; usec_t holdoff_timeout_usec;
sd_event_source *lid_switch_ignore_event_source; sd_event_source *lid_switch_ignore_event_source;
sd_event_source *power_key_long_press_event_source;
sd_event_source *reboot_key_long_press_event_source;
sd_event_source *suspend_key_long_press_event_source;
sd_event_source *hibernate_key_long_press_event_source;
uint64_t runtime_dir_size; uint64_t runtime_dir_size;
uint64_t runtime_dir_inodes; uint64_t runtime_dir_inodes;
uint64_t sessions_max; uint64_t sessions_max;

View file

@ -143,12 +143,25 @@ _SD_BEGIN_DECLARATIONS;
#define SD_MESSAGE_SYSTEM_UNDOCKED_STR SD_ID128_MAKE_STR(51,e1,71,bd,58,52,48,56,81,10,14,4c,51,7c,ca,53) #define SD_MESSAGE_SYSTEM_UNDOCKED_STR SD_ID128_MAKE_STR(51,e1,71,bd,58,52,48,56,81,10,14,4c,51,7c,ca,53)
#define SD_MESSAGE_POWER_KEY SD_ID128_MAKE(b7,2e,a4,a2,88,15,45,a0,b5,0e,20,0e,55,b9,b0,71) #define SD_MESSAGE_POWER_KEY SD_ID128_MAKE(b7,2e,a4,a2,88,15,45,a0,b5,0e,20,0e,55,b9,b0,71)
#define SD_MESSAGE_POWER_KEY_STR SD_ID128_MAKE_STR(b7,2e,a4,a2,88,15,45,a0,b5,0e,20,0e,55,b9,b0,71) #define SD_MESSAGE_POWER_KEY_STR SD_ID128_MAKE_STR(b7,2e,a4,a2,88,15,45,a0,b5,0e,20,0e,55,b9,b0,71)
#define SD_MESSAGE_POWER_KEY_LONG_PRESS SD_ID128_MAKE(3e,01,17,10,1e,b2,43,c1,b9,a5,0d,b3,49,4a,b1,0b)
#define SD_MESSAGE_POWER_KEY_LONG_PRESS_STR \
SD_ID128_MAKE_STR(3e,01,17,10,1e,b2,43,c1,b9,a5,0d,b3,49,4a,b1,0b)
#define SD_MESSAGE_REBOOT_KEY SD_ID128_MAKE(9f,a9,d2,c0,12,13,4e,c3,85,45,1f,fe,31,6f,97,d0) #define SD_MESSAGE_REBOOT_KEY SD_ID128_MAKE(9f,a9,d2,c0,12,13,4e,c3,85,45,1f,fe,31,6f,97,d0)
#define SD_MESSAGE_REBOOT_KEY_STR SD_ID128_MAKE_STR(9f,a9,d2,c0,12,13,4e,c3,85,45,1f,fe,31,6f,97,d0) #define SD_MESSAGE_REBOOT_KEY_STR SD_ID128_MAKE_STR(9f,a9,d2,c0,12,13,4e,c3,85,45,1f,fe,31,6f,97,d0)
#define SD_MESSAGE_REBOOT_KEY_LONG_PRESS SD_ID128_MAKE(f1,c5,9a,58,c9,d9,43,66,89,65,c3,37,ca,ec,59,75)
#define SD_MESSAGE_REBOOT_KEY_LONG_PRESS_STR \
SD_ID128_MAKE_STR(f1,c5,9a,58,c9,d9,43,66,89,65,c3,37,ca,ec,59,75)
#define SD_MESSAGE_SUSPEND_KEY SD_ID128_MAKE(b7,2e,a4,a2,88,15,45,a0,b5,0e,20,0e,55,b9,b0,72) #define SD_MESSAGE_SUSPEND_KEY SD_ID128_MAKE(b7,2e,a4,a2,88,15,45,a0,b5,0e,20,0e,55,b9,b0,72)
#define SD_MESSAGE_SUSPEND_KEY_STR SD_ID128_MAKE_STR(b7,2e,a4,a2,88,15,45,a0,b5,0e,20,0e,55,b9,b0,72) #define SD_MESSAGE_SUSPEND_KEY_STR SD_ID128_MAKE_STR(b7,2e,a4,a2,88,15,45,a0,b5,0e,20,0e,55,b9,b0,72)
#define SD_MESSAGE_SUSPEND_KEY_LONG_PRESS SD_ID128_MAKE(bf,da,f6,d3,12,ab,40,07,bc,1f,e4,0a,15,df,78,e8)
#define SD_MESSAGE_SUSPEND_KEY_LONG_PRESS_STR \
SD_ID128_MAKE_STR(bf,da,f6,d3,12,ab,40,07,bc,1f,e4,0a,15,df,78,e8)
#define SD_MESSAGE_HIBERNATE_KEY SD_ID128_MAKE(b7,2e,a4,a2,88,15,45,a0,b5,0e,20,0e,55,b9,b0,73) #define SD_MESSAGE_HIBERNATE_KEY SD_ID128_MAKE(b7,2e,a4,a2,88,15,45,a0,b5,0e,20,0e,55,b9,b0,73)
#define SD_MESSAGE_HIBERNATE_KEY_STR SD_ID128_MAKE_STR(b7,2e,a4,a2,88,15,45,a0,b5,0e,20,0e,55,b9,b0,73) #define SD_MESSAGE_HIBERNATE_KEY_STR SD_ID128_MAKE_STR(b7,2e,a4,a2,88,15,45,a0,b5,0e,20,0e,55,b9,b0,73)
#define SD_MESSAGE_HIBERNATE_KEY_LONG_PRESS \
SD_ID128_MAKE(16,78,36,df,6f,7f,42,8e,98,14,72,27,b2,dc,89,45)
#define SD_MESSAGE_HIBERNATE_KEY_LONG_PRESS_STR \
SD_ID128_MAKE_STR(16,78,36,df,6f,7f,42,8e,98,14,72,27,b2,dc,89,45)
#define SD_MESSAGE_INVALID_CONFIGURATION SD_ID128_MAKE(c7,72,d2,4e,9a,88,4c,be,b9,ea,12,62,5c,30,6c,01) #define SD_MESSAGE_INVALID_CONFIGURATION SD_ID128_MAKE(c7,72,d2,4e,9a,88,4c,be,b9,ea,12,62,5c,30,6c,01)
#define SD_MESSAGE_INVALID_CONFIGURATION_STR \ #define SD_MESSAGE_INVALID_CONFIGURATION_STR \