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