1 #include <hikari/switch.h>
2 
3 #include <hikari/action.h>
4 #include <hikari/memory.h>
5 #include <hikari/server.h>
6 #include <hikari/switch_config.h>
7 
8 static void
execute_action(void (* action)(void * arg),void * arg)9 execute_action(void (*action)(void *arg), void *arg)
10 {
11   if (hikari_server_in_lock_mode()) {
12     return;
13   }
14 
15   if (!hikari_server_in_normal_mode()) {
16     hikari_server_enter_normal_mode(NULL);
17   }
18 
19   action(arg);
20 }
21 
22 static void
destroy_handler(struct wl_listener * listener,void * data)23 destroy_handler(struct wl_listener *listener, void *data)
24 {
25   struct hikari_switch *swtch = wl_container_of(listener, swtch, destroy);
26 
27   hikari_switch_fini(swtch);
28 }
29 
30 static void
toggle_handler(struct wl_listener * listener,void * data)31 toggle_handler(struct wl_listener *listener, void *data)
32 {
33   struct hikari_switch *swtch = wl_container_of(listener, swtch, toggle);
34 
35   if (swtch->state == WLR_SWITCH_STATE_OFF) {
36     struct hikari_event_action *begin = &swtch->action->begin;
37     if (begin != NULL) {
38       execute_action(begin->action, begin->arg);
39     }
40     swtch->state = WLR_SWITCH_STATE_ON;
41   }
42 
43   if (swtch->state == WLR_SWITCH_STATE_ON) {
44     struct hikari_event_action *end = &swtch->action->end;
45     if (end != NULL) {
46       execute_action(end->action, end->arg);
47     }
48     swtch->state = WLR_SWITCH_STATE_OFF;
49   }
50 }
51 
52 void
hikari_switch_init(struct hikari_switch * swtch,struct wlr_input_device * device)53 hikari_switch_init(struct hikari_switch *swtch, struct wlr_input_device *device)
54 {
55   swtch->device = device;
56   swtch->state = WLR_SWITCH_STATE_OFF;
57   swtch->action = NULL;
58 
59   swtch->destroy.notify = destroy_handler;
60   wl_signal_add(&device->events.destroy, &swtch->destroy);
61 
62   wl_list_init(&swtch->toggle.link);
63 
64   wl_list_insert(&hikari_server.switches, &swtch->server_switches);
65 }
66 
67 void
hikari_switch_fini(struct hikari_switch * swtch)68 hikari_switch_fini(struct hikari_switch *swtch)
69 {
70   wl_list_remove(&swtch->destroy.link);
71   wl_list_remove(&swtch->toggle.link);
72   wl_list_remove(&swtch->server_switches);
73 }
74 
75 void
hikari_switch_configure(struct hikari_switch * swtch,struct hikari_switch_config * switch_config)76 hikari_switch_configure(
77     struct hikari_switch *swtch, struct hikari_switch_config *switch_config)
78 {
79   struct wlr_input_device *device = swtch->device;
80 
81   swtch->action = &switch_config->action;
82 
83   wl_list_remove(&swtch->toggle.link);
84   swtch->toggle.notify = toggle_handler;
85   wl_signal_add(&device->switch_device->events.toggle, &swtch->toggle);
86 }
87 
88 void
hikari_switch_reset(struct hikari_switch * swtch)89 hikari_switch_reset(struct hikari_switch *swtch)
90 {
91   swtch->action = NULL;
92 }
93