A modern Music Player Daemon based on Rockbox open source high quality audio player
libadwaita
audio
rust
zig
deno
mpris
rockbox
mpd
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2008 by Miika Pekkarinen
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22#include <stdio.h>
23#include "events.h"
24#include "panic.h"
25
26#define MAX_SYS_EVENTS 28
27
28struct sysevent {
29 unsigned short id;
30 bool oneshot;
31 union {
32 void (*cb)(unsigned short id, void *event_data);
33 void (*cb_ex)(unsigned short id, void *event_data, void *user_data);
34 } handler;
35 void *user_data;
36};
37
38static struct sysevent events[MAX_SYS_EVENTS];
39static int invalid_userdata;
40
41static bool do_add_event(unsigned short id, bool oneshot,
42 void *handler, void *user_data)
43{
44 size_t free = MAX_SYS_EVENTS;
45 struct sysevent *ev;
46 /* Check if the event already exists. & lowest free slot available */
47 for (size_t i = MAX_SYS_EVENTS - 1; i < MAX_SYS_EVENTS; i--)
48 {
49 ev = &events[i];
50 if (ev->handler.cb == NULL)
51 free = i;
52
53 if (ev->id == id && ev->handler.cb == handler && user_data == ev->user_data)
54 {
55 return false;
56 }
57 }
58
59 /* is there a free slot? */
60 if (free < MAX_SYS_EVENTS)
61 {
62 ev = &events[free];
63 ev->id = id;
64 ev->handler.cb = handler;
65 ev->user_data = user_data;
66 ev->oneshot = oneshot;
67
68 return true;
69 }
70
71 panicf("event line full");
72 return false;
73}
74
75bool add_event(unsigned short id, void (*handler)(unsigned short id, void *data))
76{
77 return do_add_event(id, false, handler, &invalid_userdata);
78}
79
80bool add_event_ex(unsigned short id, bool oneshot,
81 void (*handler)(unsigned short id, void *event_data, void *user_data), void *user_data)
82{
83 return do_add_event(id, oneshot, handler, user_data);
84}
85
86static void do_remove_event(unsigned short id, void *handler, void *user_data)
87{
88 for (size_t i = 0; i < MAX_SYS_EVENTS; i++)
89 {
90 struct sysevent *ev = &events[i];
91 if (ev->id == id && ev->handler.cb == handler && user_data == ev->user_data)
92 {
93 ev->handler.cb = NULL;
94 return;
95 }
96 }
97}
98
99void remove_event(unsigned short id, void (*handler)(unsigned short id, void *data))
100{
101 do_remove_event(id, handler, &invalid_userdata);
102}
103
104void remove_event_ex(unsigned short id,
105 void (*handler)(unsigned short id, void *event_data, void *user_data),
106 void *user_data)
107{
108 do_remove_event(id, handler, user_data);
109}
110
111void send_event(unsigned short id, void *data)
112{
113 for (size_t i = 0; i < MAX_SYS_EVENTS; i++)
114 {
115 struct sysevent *ev = &events[i];
116 if (ev->id == id && ev->handler.cb != NULL)
117 {
118 if (ev->user_data != &invalid_userdata)
119 {
120 ev->handler.cb_ex(id, data, ev->user_data);
121 if (ev->oneshot) /* only _ex events have option of oneshot */
122 ev->handler.cb = NULL;
123 }
124 else
125 ev->handler.cb(id, data);
126 }
127 }
128}