const gchar *g_module_check_init(GModule *module) { (void)module; /* Get initial state of datapipes */ call_state = datapipe_get_gint(call_state_pipe); alarm_ui_state = datapipe_get_gint(alarm_ui_state_pipe); display_state = display_state_get(); submode = datapipe_get_gint(submode_pipe); /* Append triggers/filters to datapipes */ append_input_trigger_to_datapipe(&call_state_pipe, call_state_trigger); append_input_trigger_to_datapipe(&alarm_ui_state_pipe, alarm_ui_state_trigger); append_output_trigger_to_datapipe(&display_state_pipe, display_state_trigger); append_output_trigger_to_datapipe(&submode_pipe, submode_trigger); /* PS enabled setting */ mce_gconf_notifier_add(MCE_GCONF_PROXIMITY_PATH, MCE_GCONF_PROXIMITY_PS_ENABLED_PATH, use_ps_conf_cb, &use_ps_conf_id); mce_gconf_get_bool(MCE_GCONF_PROXIMITY_PS_ENABLED_PATH, &use_ps_conf_value); /* enable/disable sensor based on initial conditions */ update_proximity_monitor(); return NULL; }
/** * Send the call state and type * * @param method_call A DBusMessage to reply to; * pass NULL to send a signal instead * @param call_state A string representation of an alternate state * to send instead of the real call state * @param call_type A string representation of an alternate type * to send instead of the real call type * @return TRUE on success, FALSE on failure */ static gboolean send_call_state(DBusMessage *const method_call, const gchar *const call_state, const gchar *const call_type) { DBusMessage *msg = NULL; gboolean status = FALSE; const gchar *sstate; const gchar *stype; /* Allow spoofing */ if (call_state != NULL) sstate = call_state; else sstate = call_state_repr(datapipe_get_gint(call_state_pipe)); if (call_type != NULL) stype = call_type; else stype = call_type_repr(datapipe_get_gint(call_type_pipe)); /* If method_call is set, send a reply, * otherwise, send a signal */ if (method_call != NULL) { msg = dbus_new_method_reply(method_call); } else { /* sig_call_state_ind */ msg = dbus_new_signal(MCE_SIGNAL_PATH, MCE_SIGNAL_IF, MCE_CALL_STATE_SIG); } /* Append the call state and call type */ if (dbus_message_append_args(msg, DBUS_TYPE_STRING, &sstate, DBUS_TYPE_STRING, &stype, DBUS_TYPE_INVALID) == FALSE) { mce_log(LL_CRIT, "Failed to append %sarguments to D-Bus message " "for %s.%s", method_call ? "reply " : "", method_call ? MCE_REQUEST_IF : MCE_SIGNAL_IF, method_call ? MCE_CALL_STATE_GET : MCE_CALL_STATE_SIG); dbus_message_unref(msg); goto EXIT; } /* Send the message */ status = dbus_send_message(msg); EXIT: return status; }
/** * Logic for long key press * * @return TRUE on success, FALSE on failure */ static gboolean handle_longpress(void) { system_state_t state = datapipe_get_gint(system_state_pipe); alarm_ui_state_t alarm_ui_state = datapipe_get_gint(alarm_ui_state_pipe); submode_t submode = mce_get_submode_int32(); gboolean status = TRUE; /* Ignore keypress if the alarm UI is visible */ if ((alarm_ui_state == MCE_ALARM_UI_VISIBLE_INT32) || (alarm_ui_state == MCE_ALARM_UI_RINGING_INT32)) goto EXIT; /* Ignore if we're already shutting down/rebooting */ switch (state) { case MCE_STATE_SHUTDOWN: case MCE_STATE_REBOOT: status = FALSE; break; case MCE_STATE_ACTDEAD: request_powerup(); break; case MCE_STATE_USER: /* If softoff is enabled, wake up * Otherwise, perform long press action */ if ((submode & MCE_SOFTOFF_SUBMODE)) { request_soft_poweron(); } else { generic_powerkey_handler(longpressaction, longpresssignal); } break; default: /* If no special cases are needed, * just do a regular shutdown */ mce_log(LL_WARN, "Requesting shutdown; state: %d", state); request_normal_shutdown(); break; } EXIT: return status; }
const gchar *g_module_check_init(GModule *module) { (void)module; /* Config from ini-files */ dbltap_ctrl_path = mce_conf_get_string(MCE_CONF_DOUBLETAP_GROUP, MCE_CONF_DOUBLETAP_CONTROL_PATH, NULL); dbltap_enable_val = mce_conf_get_string(MCE_CONF_DOUBLETAP_GROUP, MCE_CONF_DOUBLETAP_ENABLE_VALUE, "1"); dbltap_disable_val = mce_conf_get_string(MCE_CONF_DOUBLETAP_GROUP, MCE_CONF_DOUBLETAP_DISABLE_VALUE, "0"); if( !dbltap_ctrl_path || !dbltap_enable_val || !dbltap_disable_val ) { mce_log(LL_NOTICE, "no double tap wakeup controls defined"); goto EXIT; } dbltap_probe_sleep_mode_controls(); /* Runtime configuration settings */ mce_gconf_notifier_add(MCE_GCONF_DOUBLETAP_PATH, MCE_GCONF_DOUBLETAP_MODE, dbltap_mode_gconf_cb, &dbltap_mode_gconf_id); gint mode = DBLTAP_ENABLE_DEFAULT; mce_gconf_get_int(MCE_GCONF_DOUBLETAP_MODE, &mode); dbltap_mode = mode; /* Append triggers/filters to datapipes */ append_output_trigger_to_datapipe(&proximity_sensor_pipe, dbltap_proximity_trigger); append_output_trigger_to_datapipe(&proximity_blank_pipe, dbltap_proximity_blank_trigger); append_output_trigger_to_datapipe(&lid_cover_policy_pipe, dbltap_lid_cover_policy_trigger); /* Get initial state of datapipes */ dbltap_ps_state = datapipe_get_gint(proximity_sensor_pipe); dbltap_ps_blank = datapipe_get_gint(proximity_blank_pipe); dbltap_lid_cover_policy = datapipe_get_gint(lid_cover_policy_pipe); /* enable/disable double tap wakeups based on initial conditions */ dbltap_rethink(); EXIT: return NULL; }
/** Generate activity from proximity sensor uncover * * @param data proximity sensor state as void pointer */ static void proximity_sensor_trigger(gconstpointer data) { static cover_state_t old_proximity_state = COVER_OPEN; cover_state_t proximity_state = GPOINTER_TO_INT(data); /* generate activity if proximity sensor is * uncovered and there is a incoming call */ if( old_proximity_state == proximity_state ) goto EXIT; old_proximity_state = proximity_state; if( proximity_state != COVER_OPEN ) goto EXIT; call_state_t call_state = datapipe_get_gint(call_state_pipe); if( call_state != CALL_STATE_RINGING ) goto EXIT; mce_log(LL_INFO, "proximity -> uncovered, call = ringing"); execute_datapipe(&device_inactive_pipe, GINT_TO_POINTER(FALSE), USE_INDATA, CACHE_INDATA); EXIT: return; }
const gchar *g_module_check_init(GModule *module) { (void)module; /* Get initial state of datapipes */ call_state = datapipe_get_gint(call_state_pipe); alarm_ui_state = datapipe_get_gint(alarm_ui_state_pipe); display_state = display_state_get(); submode = datapipe_get_gint(submode_pipe); /* Append triggers/filters to datapipes */ append_input_trigger_to_datapipe(&call_state_pipe, call_state_trigger); append_input_trigger_to_datapipe(&alarm_ui_state_pipe, alarm_ui_state_trigger); append_output_trigger_to_datapipe(&display_state_pipe, display_state_trigger); append_output_trigger_to_datapipe(&submode_pipe, submode_trigger); /* PS enabled setting */ mce_setting_track_bool(MCE_SETTING_PROXIMITY_PS_ENABLED, &use_ps_conf_value, MCE_DEFAULT_PROXIMITY_PS_ENABLED, use_ps_conf_cb, &use_ps_conf_id); /* PS acts as LID sensor */ mce_setting_track_bool(MCE_SETTING_PROXIMITY_PS_ACTS_AS_LID, &ps_acts_as_lid, MCE_DEFAULT_PROXIMITY_PS_ACTS_AS_LID, use_ps_conf_cb, &ps_acts_as_lid_conf_id); /* If the proximity sensor input is used for toggling * lid state, we must take care not to leave proximity * tracking to covered state. */ if( ps_acts_as_lid ) report_proximity(COVER_OPEN); /* enable/disable sensor based on initial conditions */ update_proximity_monitor(); return NULL; }
/** Sync active radio state -> master_radio_enabled_pipe */ static void mrs_datapipe_update_master_radio_enabled(void) { int prev = datapipe_get_gint(master_radio_enabled_pipe); int next = (active_radio_states & MCE_RADIO_STATE_MASTER) ? 1 : 0; if( prev != next ) datapipe_exec_full(&master_radio_enabled_pipe, GINT_TO_POINTER(next)); }
/** * Datapipe trigger for the [power] key * * @param data A pointer to the input_event struct */ static void powerkey_trigger(gconstpointer const data) { system_state_t system_state = datapipe_get_gint(system_state_pipe); submode_t submode = mce_get_submode_int32(); struct input_event const *const *evp; struct input_event const *ev; /* Don't dereference until we know it's safe */ if (data == NULL) goto EXIT; evp = data; ev = *evp; if ((ev != NULL) && (ev->code == KEY_POWER)) { /* If set, the [power] key was pressed */ if (ev->value == 1) { mce_log(LL_DEBUG, "[power] pressed"); /* Are we waiting for a doublepress? */ if (doublepress_timeout_cb_id != 0) { handle_shortpress(); } else if ((system_state == MCE_STATE_ACTDEAD) || ((submode & MCE_SOFTOFF_SUBMODE) != 0)) { /* Setup new timeout */ execute_datapipe_output_triggers(&led_pattern_activate_pipe, MCE_LED_PATTERN_POWER_ON, USE_INDATA); /* Shorter delay for startup * than for shutdown */ setup_powerkey_timeout(mediumdelay); } else { setup_powerkey_timeout(longdelay); } } else if (ev->value == 0) { mce_log(LL_DEBUG, "[power] released"); /* Short key press */ if (powerkey_timeout_cb_id != 0) { handle_shortpress(); if ((system_state == MCE_STATE_ACTDEAD) || ((submode & MCE_SOFTOFF_SUBMODE) != 0)) { execute_datapipe_output_triggers(&led_pattern_deactivate_pipe, MCE_LED_PATTERN_POWER_ON, USE_INDATA); } } } } EXIT: return; }
static void alarm_sync_state_to_datapipe(alarm_ui_state_t state) { if( datapipe_get_gint(alarm_ui_state_pipe) == state ) goto EXIT; mce_log(LL_DEVEL, "alarm sate = %s", alarm_state_repr(state)); execute_datapipe(&alarm_ui_state_pipe, GINT_TO_POINTER(state), USE_INDATA, CACHE_INDATA); EXIT: return; }
/** Broadcast faked lid input state within mce * * @param state COVER_CLOSED, COVER_OPEN or COVER_UNDEF */ static void report_lid_input(cover_state_t state) { cover_state_t old_state = datapipe_get_gint(lid_cover_sensor_pipe); if( state != old_state ) { mce_log(LL_NOTICE, "state: %s -> %s", cover_state_repr(old_state), cover_state_repr(state)); execute_datapipe(&lid_cover_sensor_pipe, GINT_TO_POINTER(state), USE_INDATA, CACHE_INDATA); } }
/** * Set the MCE submode flags * * @param submode All submodes to set OR:ed together * @return TRUE on success, FALSE on failure */ static gboolean mce_set_submode_int32(const submode_t submode) { submode_t old_submode = datapipe_get_gint(submode_pipe); if (old_submode == submode) goto EXIT; mce_log(LL_NOTICE, "submode change: %s", submode_change_repr(old_submode, submode)); datapipe_exec_full(&submode_pipe, GINT_TO_POINTER(submode)); EXIT: return TRUE; }
/** * Setup inactivity timeout */ static void setup_inactivity_timeout(void) { gint timeout = datapipe_get_gint(inactivity_timeout_pipe); cancel_inactivity_timeout(); /* Sanitise timeout */ if (timeout <= 0) timeout = 30; /* Setup new timeout */ inactivity_timeout_cb_id = g_timeout_add_seconds(timeout, inactivity_timeout_cb, NULL); }
/** * Request normal shutdown */ void mce_dsme_request_normal_shutdown(void) { if( datapipe_get_gint(update_mode_pipe) ) { mce_log(LL_WARN, "shutdown blocked; os update in progress"); goto EXIT; } /* Set up the message */ DSM_MSGTYPE_SHUTDOWN_REQ msg = DSME_MSG_INIT(DSM_MSGTYPE_SHUTDOWN_REQ); /* Send the message */ mce_dsme_send(&msg, "DSM_MSGTYPE_SHUTDOWN_REQ(DSME_NORMAL_SHUTDOWN)"); EXIT: return; }
/** * Request reboot */ void mce_dsme_request_reboot(void) { if( datapipe_get_gint(update_mode_pipe) ) { mce_log(LL_WARN, "reboot blocked; os update in progress"); goto EXIT; } /* Set up the message */ DSM_MSGTYPE_REBOOT_REQ msg = DSME_MSG_INIT(DSM_MSGTYPE_REBOOT_REQ); /* Send the message */ mce_dsme_send(&msg, "DSM_MSGTYPE_REBOOT_REQ"); EXIT: return; }
/** * Timeout callback for double key press * * @param data Unused * @return Always returns FALSE, to disable the timeout */ static gboolean doublepress_timeout_cb(gpointer data) { system_state_t system_state = datapipe_get_gint(system_state_pipe); (void)data; doublepress_timeout_cb_id = 0; /* doublepress timer expired without any secondary press; * thus this was a short press */ if (system_state == MCE_STATE_USER) generic_powerkey_handler(shortpressaction, shortpresssignal); return FALSE; }
/** * Set the MCE submode flags * * @param submode All submodes to set OR:ed together * @return TRUE on success, FALSE on failure */ static gboolean mce_set_submode_int32(const submode_t submode) { submode_t old_submode = datapipe_get_gint(submode_pipe); if (old_submode == submode) goto EXIT; if( mce_log_p(LL_NOTICE) ) { char *delta = mce_submode_change(old_submode, submode); mce_log(LL_NOTICE, "submode change: %s", delta ?: "???"); free(delta); } execute_datapipe(&submode_pipe, GINT_TO_POINTER(submode), USE_INDATA, CACHE_INDATA); EXIT: return TRUE; }
/** Broadcast proximity state within MCE * * @param state COVER_CLOSED or COVER_OPEN */ static void report_proximity(cover_state_t state) { /* Get current proximity datapipe value */ cover_state_t old_state = datapipe_get_gint(proximity_sensor_pipe); /* Execute datapipe if state has changed */ if( old_state != state ) { mce_log(LL_NOTICE, "state: %s -> %s", cover_state_repr(old_state), cover_state_repr(state)); execute_datapipe(&proximity_sensor_pipe, GINT_TO_POINTER(state), USE_INDATA, CACHE_INDATA); } }
/** Broadcast proximity state within MCE * * @param state COVER_CLOSED or COVER_OPEN */ static void report_proximity(cover_state_t state) { /* Get current proximity datapipe value */ cover_state_t old_state = datapipe_get_gint(proximity_sensor_pipe); /* Execute datapipe if state has changed */ /* FIXME: figure out where things break down if we do not * omit the non-change datapipe execute ... */ //if( old_state != state ) { mce_log(LL_NOTICE, "state: %s -> %s", cover_state_repr(old_state), cover_state_repr(state)); execute_datapipe(&proximity_sensor_pipe, GINT_TO_POINTER(state), USE_INDATA, CACHE_INDATA); } /* Update last-seen proximity state */ old_proximity_sensor_state = state; }
/** * Callback for pending I/O from dsmesock * * XXX: is the error policy reasonable? * * @param source Unused * @param condition Unused * @param data Unused * @return TRUE on success, FALSE on failure */ static gboolean io_data_ready_cb(GIOChannel *source, GIOCondition condition, gpointer data) { dsmemsg_generic_t *msg; DSM_MSGTYPE_STATE_CHANGE_IND *msg2; system_state_t oldstate = datapipe_get_gint(system_state_pipe); system_state_t newstate = MCE_STATE_UNDEF; (void)source; (void)condition; (void)data; if (dsme_disabled == TRUE) goto EXIT; if ((msg = (dsmemsg_generic_t *)dsmesock_receive(dsme_conn)) == NULL) goto EXIT; if (DSMEMSG_CAST(DSM_MSGTYPE_CLOSE, msg)) { /* DSME socket closed: try once to reopen; * if that fails, exit */ mce_log(LL_ERR, "DSME socket closed; trying to reopen"); if ((init_dsmesock()) == FALSE) { // FIXME: this is not how one should exit from mainloop mce_quit_mainloop(); exit(EXIT_FAILURE); } } else if (DSMEMSG_CAST(DSM_MSGTYPE_PROCESSWD_PING, msg)) { dsme_send_pong(); } else if ((msg2 = DSMEMSG_CAST(DSM_MSGTYPE_STATE_CHANGE_IND, msg))) { newstate = normalise_dsme_state(msg2->state); mce_log(LL_DEBUG, "DSME device state change: %d", newstate); /* If we're changing to a different state, * add the transition flag, UNLESS the old state * was MCE_STATE_UNDEF */ if ((oldstate != newstate) && (oldstate != MCE_STATE_UNDEF)) mce_add_submode_int32(MCE_TRANSITION_SUBMODE); switch (newstate) { case MCE_STATE_USER: execute_datapipe_output_triggers(&led_pattern_activate_pipe, MCE_LED_PATTERN_DEVICE_ON, USE_INDATA); break; case MCE_STATE_ACTDEAD: case MCE_STATE_BOOT: case MCE_STATE_UNDEF: break; case MCE_STATE_SHUTDOWN: case MCE_STATE_REBOOT: execute_datapipe_output_triggers(&led_pattern_deactivate_pipe, MCE_LED_PATTERN_DEVICE_ON, USE_INDATA); break; default: break; } execute_datapipe(&system_state_pipe, GINT_TO_POINTER(newstate), USE_INDATA, CACHE_INDATA); } else { mce_log(LL_DEBUG, "Unknown message type (%x) received from DSME!", msg->type_); /* <- unholy access of a private member */ } free(msg); EXIT: return TRUE; }
const gchar *g_module_check_init(GModule *module) { (void)module; /* Read lux ramps from configuration */ als_filter_load_config(&lut_display); als_filter_load_config(&lut_led); als_filter_load_config(&lut_key); /* Get intial display state */ display_state = datapipe_get_gint(display_state_pipe); /* Append triggers/filters to datapipes */ append_filter_to_datapipe(&display_brightness_pipe, display_brightness_filter); append_filter_to_datapipe(&led_brightness_pipe, led_brightness_filter); append_filter_to_datapipe(&key_backlight_pipe, key_backlight_filter); append_output_trigger_to_datapipe(&display_state_pipe, display_state_trigger); /* Add dbus method call handlers */ mce_dbus_handler_add(MCE_REQUEST_IF, MCE_REQ_ALS_ENABLE, NULL, DBUS_MESSAGE_TYPE_METHOD_CALL, als_enable_req_dbus_cb); mce_dbus_handler_add(MCE_REQUEST_IF, MCE_REQ_ALS_DISABLE, NULL, DBUS_MESSAGE_TYPE_METHOD_CALL, als_disable_req_dbus_cb); mce_dbus_handler_add(MCE_REQUEST_IF, MCE_COLOR_PROFILE_GET, NULL, DBUS_MESSAGE_TYPE_METHOD_CALL, color_profile_get_req_dbus_cb); mce_dbus_handler_add(MCE_REQUEST_IF, MCE_COLOR_PROFILE_IDS_GET, NULL, DBUS_MESSAGE_TYPE_METHOD_CALL, color_profile_ids_get_req_dbus_cb); mce_dbus_handler_add(MCE_REQUEST_IF, MCE_COLOR_PROFILE_CHANGE_REQ, NULL, DBUS_MESSAGE_TYPE_METHOD_CALL, color_profile_change_req_dbus_cb); /* ALS enabled setting */ mce_gconf_notifier_add(MCE_GCONF_DISPLAY_PATH, MCE_GCONF_DISPLAY_ALS_ENABLED_PATH, use_als_gconf_cb, &use_als_gconf_id); mce_gconf_get_bool(MCE_GCONF_DISPLAY_ALS_ENABLED_PATH, &use_als_flag); /* Color profile setting */ mce_gconf_notifier_add(MCE_GCONF_DISPLAY_PATH, MCE_GCONF_DISPLAY_COLOR_PROFILE_PATH, color_profile_gconf_cb, &color_profile_gconf_id); if( init_color_profiles() ) init_current_color_profile(); rethink_als_status(); return NULL; }
/** * Remove flags from the MCE submode * * @param submode submode(s) to remove OR:ed together * @return TRUE on success, FALSE on failure */ gboolean mce_rem_submode_int32(const submode_t submode) { submode_t old_submode = datapipe_get_gint(submode_pipe); return mce_set_submode_int32(old_submode & ~submode); }
submode_t mce_get_submode_int32(void) { submode_t submode = datapipe_get_gint(submode_pipe); return submode; }
/** * Datapipe filter for inactivity * * @param data The unfiltered inactivity state; * TRUE if the device is inactive, * FALSE if the device is active * @return The filtered inactivity state; * TRUE if the device is inactive, * FALSE if the device is active */ static gpointer device_inactive_filter(gpointer data) { static gboolean old_device_inactive = FALSE; alarm_ui_state_t alarm_ui_state = datapipe_get_gint(alarm_ui_state_pipe); submode_t submode = mce_get_submode_int32(); cover_state_t proximity_state = proximity_state_get(); display_state_t display_state = display_state_get(); system_state_t system_state = datapipe_get_gint(system_state_pipe); call_state_t call_state = datapipe_get_gint(call_state_pipe); device_inactive = GPOINTER_TO_INT(data); /* nothing to filter if we are already inactive */ if( device_inactive ) goto EXIT; /* Never filter inactivity if display is in dimmed state. * * Whether we have arrived to dimmed state via expected or * unexpected routes, the touch input is active and ui side * event eater will ignore only the first event. If we do * not allow activity (and turn on the display) we will get * ui interaction in odd looking dimmed state that then gets * abruptly ended by blanking timer. */ if( display_state == MCE_DISPLAY_DIM ) goto EXIT; /* system state must be USER or ACT DEAD */ switch( system_state ) { case MCE_STATE_USER: case MCE_STATE_ACTDEAD: break; default: mce_log(LL_DEBUG, "system_state != USER|ACTDEAD" "; ignoring activity"); device_inactive = TRUE; goto EXIT; } /* tklock must be off, or there must be alarms or calls */ if( submode & MCE_TKLOCK_SUBMODE ) { gboolean have_alarms = FALSE; gboolean have_calls = FALSE; gboolean display_on = FALSE; switch( alarm_ui_state ) { case MCE_ALARM_UI_RINGING_INT32: case MCE_ALARM_UI_VISIBLE_INT32: have_alarms = TRUE; break; default: break; } switch( call_state ) { case CALL_STATE_RINGING: case CALL_STATE_ACTIVE: have_calls = TRUE; default: break; } if( display_state == MCE_DISPLAY_ON ) display_on = TRUE; if( !display_on && !have_alarms && !have_calls ) { mce_log(LL_DEBUG, "tklock enabled, no alarms or calls;" " ignoring activity"); device_inactive = TRUE; goto EXIT; } } /* if proximity is covered, display must not be off */ if( proximity_state == COVER_CLOSED ) { switch( display_state ) { case MCE_DISPLAY_OFF: case MCE_DISPLAY_LPM_OFF: case MCE_DISPLAY_LPM_ON: case MCE_DISPLAY_POWER_UP: case MCE_DISPLAY_POWER_DOWN: mce_log(LL_DEBUG, "display=off, proximity=covered; ignoring activity"); device_inactive = TRUE; goto EXIT; default: case MCE_DISPLAY_UNDEF: case MCE_DISPLAY_DIM: case MCE_DISPLAY_ON: break; } } EXIT: /* React to activity */ if( !device_inactive ) { call_activity_callbacks(); setup_inactivity_timeout(); } /* Handle inactivity state change */ if( old_device_inactive != device_inactive ) { old_device_inactive = device_inactive; send_inactivity_status(NULL); } /* Return filtered activity state */ return GINT_TO_POINTER(device_inactive); }
/** * Generic logic for key presses * * @param action The action to take * @param dbus_signal A D-Bus signal to send */ static void generic_powerkey_handler(poweraction_t action, gchar *dbus_signal) { alarm_ui_state_t alarm_ui_state = datapipe_get_gint(alarm_ui_state_pipe); submode_t submode = mce_get_submode_int32(); /* Ignore keypress if the alarm UI is visible */ if ((alarm_ui_state == MCE_ALARM_UI_VISIBLE_INT32) || (alarm_ui_state == MCE_ALARM_UI_RINGING_INT32)) goto EXIT; switch (action) { case POWER_DISABLED: break; case POWER_POWEROFF: default: /* Do not shutdown if the tklock is active * or if we're in alarm state */ if ((submode & MCE_TKLOCK_SUBMODE) == 0) { mce_log(LL_WARN, "Requesting shutdown (action: %d)", action); request_normal_shutdown(); } break; case POWER_SOFT_POWEROFF: /* Only soft poweroff if the tklock isn't active */ if ((submode & MCE_TKLOCK_SUBMODE) == 0) { request_soft_poweroff(); } break; case POWER_TKLOCK_LOCK: /* Request enabling of touchscreen/keypad lock * if the tklock isn't already active */ if ((submode & MCE_TKLOCK_SUBMODE) == 0) { execute_datapipe(&tk_lock_pipe, GINT_TO_POINTER(LOCK_ON), USE_INDATA, CACHE_INDATA); } else if ((submode & MCE_MALF_SUBMODE) != 0) { execute_datapipe(&tk_lock_pipe, GINT_TO_POINTER(LOCK_OFF), USE_INDATA, CACHE_INDATA); } break; case POWER_TKLOCK_UNLOCK: /* Request disabling of touchscreen/keypad lock * if the tklock isn't already inactive */ if ((submode & MCE_TKLOCK_SUBMODE) != 0) { execute_datapipe(&tk_lock_pipe, GINT_TO_POINTER(LOCK_OFF), USE_INDATA, CACHE_INDATA); } break; case POWER_TKLOCK_BOTH: /* Request enabling of touchscreen/keypad lock * if the tklock isn't active, * and disabling if the tklock is active */ if ((submode & MCE_TKLOCK_SUBMODE) == 0) { execute_datapipe(&tk_lock_pipe, GINT_TO_POINTER(LOCK_ON), USE_INDATA, CACHE_INDATA); } else { execute_datapipe(&tk_lock_pipe, GINT_TO_POINTER(LOCK_OFF), USE_INDATA, CACHE_INDATA); } break; case POWER_DBUS_SIGNAL: /* Send a D-Bus signal */ dbus_send(NULL, MCE_REQUEST_PATH, MCE_REQUEST_IF, dbus_signal, NULL, DBUS_TYPE_INVALID); } EXIT: return; }