A modern Music Player Daemon based on Rockbox open source high quality audio player
libadwaita audio rust zig deno mpris rockbox mpd
at master 128 lines 3.8 kB view raw
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}