blob: 8015442cc236978e14085ca8e036f1361619f668 [file] [log] [blame]
Miika Pekkarinen19c6e662008-03-16 13:55:16 +00001/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2008 by Miika Pekkarinen
11 *
Daniel Stenberg2acc0ac2008-06-28 18:10:04 +000012 * 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.
Miika Pekkarinen19c6e662008-03-16 13:55:16 +000016 *
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
Thomas Martitzd85c3ec2009-10-20 21:54:59 +000026#define MAX_SYS_EVENTS 28
Bertrik Sikken869fbfc2008-05-20 19:20:28 +000027
Miika Pekkarinen19c6e662008-03-16 13:55:16 +000028struct sysevent {
29 unsigned short id;
Jonathan Gordona67e5d82008-03-17 05:22:53 +000030 bool oneshot;
Thomas Martitz470989b2014-03-14 23:15:16 +010031 bool has_user_data;
32 union {
33 void (*callback)(unsigned short id, void *event_data);
34 struct {
35 void (*callback2)(unsigned short id, void *event_data, void *user_data);
36 void *user_data;
37 };
38 } handler;
Miika Pekkarinen19c6e662008-03-16 13:55:16 +000039};
40
Bertrik Sikken869fbfc2008-05-20 19:20:28 +000041static struct sysevent events[MAX_SYS_EVENTS];
Miika Pekkarinen19c6e662008-03-16 13:55:16 +000042
Thomas Martitz470989b2014-03-14 23:15:16 +010043static bool do_add_event(unsigned short id, bool oneshot, bool user_data_valid,
44 void *handler, void *user_data)
Miika Pekkarinen19c6e662008-03-16 13:55:16 +000045{
46 int i;
47
Bertrik Sikkenf4eb0ee2008-04-27 19:34:41 +000048 /* Check if the event already exists. */
Miika Pekkarinen19c6e662008-03-16 13:55:16 +000049 for (i = 0; i < MAX_SYS_EVENTS; i++)
50 {
Thomas Martitz470989b2014-03-14 23:15:16 +010051 if (events[i].handler.callback == handler && events[i].id == id
Thomas Martitz915bc092014-03-15 02:23:43 +010052 && (!user_data_valid || (user_data == events[i].handler.user_data)))
Miika Pekkarinen19c6e662008-03-16 13:55:16 +000053 return false;
54 }
55
56 /* Try to find a free slot. */
57 for (i = 0; i < MAX_SYS_EVENTS; i++)
58 {
Thomas Martitz470989b2014-03-14 23:15:16 +010059 if (events[i].handler.callback == NULL)
Miika Pekkarinen19c6e662008-03-16 13:55:16 +000060 {
61 events[i].id = id;
Jonathan Gordona67e5d82008-03-17 05:22:53 +000062 events[i].oneshot = oneshot;
Thomas Martitz470989b2014-03-14 23:15:16 +010063 if ((events[i].has_user_data = user_data_valid))
64 events[i].handler.user_data = user_data;
65 events[i].handler.callback = handler;
Miika Pekkarinen19c6e662008-03-16 13:55:16 +000066 return true;
67 }
68 }
69
70 panicf("event line full");
71 return false;
72}
73
Thomas Martitz470989b2014-03-14 23:15:16 +010074bool add_event(unsigned short id, void (*handler)(unsigned short id, void *data))
75{
76 return do_add_event(id, false, false, handler, NULL);
77}
78
79bool add_event_ex(unsigned short id, bool oneshot, void (*handler)(unsigned short id, void *event_data, void *user_data), void *user_data)
80{
81 return do_add_event(id, oneshot, true, handler, user_data);
82}
83
Thomas Jaroschfdd4aef2015-01-05 18:44:36 +010084static void do_remove_event(unsigned short id, bool user_data_valid,
Thomas Martitz470989b2014-03-14 23:15:16 +010085 void *handler, void *user_data)
Miika Pekkarinen19c6e662008-03-16 13:55:16 +000086{
87 int i;
88
89 for (i = 0; i < MAX_SYS_EVENTS; i++)
90 {
Thomas Martitz470989b2014-03-14 23:15:16 +010091 if (events[i].id == id && events[i].handler.callback == handler
Thomas Martitz915bc092014-03-15 02:23:43 +010092 && (!user_data_valid || (user_data == events[i].handler.user_data)))
Miika Pekkarinen19c6e662008-03-16 13:55:16 +000093 {
Thomas Martitz470989b2014-03-14 23:15:16 +010094 events[i].handler.callback = NULL;
Miika Pekkarinen19c6e662008-03-16 13:55:16 +000095 return;
96 }
97 }
Miika Pekkarinen19c6e662008-03-16 13:55:16 +000098}
99
Thomas Martitz470989b2014-03-14 23:15:16 +0100100void remove_event(unsigned short id, void (*handler)(unsigned short id, void *data))
101{
102 do_remove_event(id, false, handler, NULL);
103}
104
105void remove_event_ex(unsigned short id,
106 void (*handler)(unsigned short id, void *event_data, void *user_data),
107 void *user_data)
108{
109 do_remove_event(id, true, handler, user_data);
110}
111
Jonathan Gordona67e5d82008-03-17 05:22:53 +0000112void send_event(unsigned short id, void *data)
Miika Pekkarinen19c6e662008-03-16 13:55:16 +0000113{
114 int i;
115
116 for (i = 0; i < MAX_SYS_EVENTS; i++)
117 {
Thomas Martitz470989b2014-03-14 23:15:16 +0100118 if (events[i].id == id && events[i].handler.callback != NULL)
Miika Pekkarinen19c6e662008-03-16 13:55:16 +0000119 {
Thomas Martitz470989b2014-03-14 23:15:16 +0100120 if (events[i].has_user_data)
121 events[i].handler.callback2(id, data, events[i].handler.user_data);
122 else
123 events[i].handler.callback(id, data);
Miika Pekkarinen19c6e662008-03-16 13:55:16 +0000124
Jonathan Gordona67e5d82008-03-17 05:22:53 +0000125 if (events[i].oneshot)
Thomas Martitz470989b2014-03-14 23:15:16 +0100126 events[i].handler.callback = NULL;
Miika Pekkarinen19c6e662008-03-16 13:55:16 +0000127 }
128 }
129}