--- /dev/null
+/*
+ * deviced
+ *
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <libinput.h>
+#include <glib.h>
+
+#include "core/devices.h"
+#include "shared/log.h"
+
+#define KEYCODE_LEFTKEY 114
+#define KEYCODE_RIGHTKEY 116
+
+#define KEYVALUE_PRESS 1
+#define KEYVALUE_RELEASE 0
+
+#define LONGPRESS_INTERVAL 3000 /* milisecond */
+
+static guint longpress_timer_id;
+
+static gboolean longpressed_cb(void *data)
+{
+ const struct device_ops *power_device;
+
+ longpress_timer_id = 0;
+
+ power_device = find_device("power");
+ if (check_default(power_device))
+ return G_SOURCE_REMOVE;
+
+ if (power_device->execute) {
+ _D("longkey pressed, do poweroff");
+ power_device->execute("poweroff");
+ }
+
+ return G_SOURCE_REMOVE;
+}
+
+static void start_longpress_timer(void)
+{
+ if (longpress_timer_id) {
+ g_source_remove(longpress_timer_id);
+ longpress_timer_id = 0;
+ }
+
+ longpress_timer_id = g_timeout_add(LONGPRESS_INTERVAL, longpressed_cb, NULL);
+}
+
+static void stop_longpress_timer(void)
+{
+ if (longpress_timer_id) {
+ g_source_remove(longpress_timer_id);
+ longpress_timer_id = 0;
+ }
+}
+
+/* poweroff if left button is pressed longer than LONGPRESS_INTERVAL */
+static void input_event_handler(struct libinput_event *e)
+{
+ struct libinput_event_keyboard *ek;
+ int keycode, keyvalue;
+
+ if (libinput_event_get_type(e) != LIBINPUT_EVENT_KEYBOARD_KEY)
+ return;
+
+ ek = libinput_event_get_keyboard_event(e);
+ keycode = libinput_event_keyboard_get_key(ek);
+ keyvalue = libinput_event_keyboard_get_key_state(ek);
+
+ _D("key input: code=%d, value=%d", keycode, keyvalue);
+
+ if (keycode == KEYCODE_LEFTKEY) {
+ if (keyvalue == KEYVALUE_PRESS)
+ start_longpress_timer();
+ else if (keyvalue == KEYVALUE_RELEASE)
+ stop_longpress_timer();
+ }
+}
+
+static void input_event_handler_init(void *data)
+{
+ const struct device_ops *input_device;
+
+ input_device = find_device("input");
+ if (check_default(input_device)) {
+ _E("There is no input device");
+ return;
+ }
+
+ if (input_device->init) {
+ _D("[%s] Initialization.", input_device->name);
+ input_device->init(input_event_handler);
+ }
+}
+
+static void input_event_handler_exit(void *data)
+{
+ const struct device_ops *input_device;
+
+ input_device = find_device("input");
+ if (check_default(input_device)) {
+ _E("There is no input device");
+ return;
+ }
+
+ if (input_device->exit)
+ input_device->exit(NULL);
+}
+
+static const struct device_ops input_event_handler_device_ops = {
+ DECLARE_NAME_LEN("input-event-handler"),
+ .init = input_event_handler_init,
+ .exit = input_event_handler_exit,
+};
+
+DEVICE_OPS_REGISTER(&input_event_handler_device_ops);