A modern Music Player Daemon based on Rockbox open source high quality audio player
libadwaita audio rust zig deno mpris rockbox mpd
at master 137 lines 4.0 kB view raw
1/*************************************************************************** 2 * __________ __ ___. 3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___ 4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / 5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < 6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ 7 * \/ \/ \/ \/ \/ 8 * $Id$ 9 * 10 * Copyright (C) 2022 Aidan MacDonald 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 "plugin.h" 23#include "logf.h" 24 25#undef DEBUGF 26#define DEBUGF(...) 27//#define DEBUGF printf 28 29#define EV_EXIT MAKE_SYS_EVENT(SYS_EVENT_CLS_PRIVATE, 0xFF) 30 31unsigned char stack[DEFAULT_STACK_SIZE]; 32struct event_queue queue; 33int thread_id; 34const char* state = "none"; 35const char* prev_state = "none"; 36 37static void main_loop(void) 38{ 39 bool exiting = false; 40 struct queue_event ev; 41 42 while(true) { 43 rb->queue_wait(&queue, &ev); 44 45 /* events that are handled whether exiting or not */ 46 switch(ev.id) { 47 case EV_EXIT: 48 return; 49 } 50 51 if(exiting) 52 continue; 53 54 /* events handled only when not exiting */ 55 switch(ev.id) { 56 case SYS_USB_CONNECTED: 57 prev_state = state; 58 state = "connected"; 59 logf("test_usb: connect ack %ld", *rb->current_tick); 60 DEBUGF("test_usb: connect ack %ld\n", *rb->current_tick); 61 rb->usb_acknowledge(SYS_USB_CONNECTED_ACK); 62 break; 63 64 case SYS_USB_DISCONNECTED: 65 prev_state = state; 66 state = "disconnected"; 67 logf("test_usb: disconnect %ld", *rb->current_tick); 68 DEBUGF("test_usb: disconnect %ld\n", *rb->current_tick); 69 break; 70 71 case SYS_POWEROFF: 72 case SYS_REBOOT: 73 prev_state = state; 74 state = "exiting"; 75 exiting = true; 76 break; 77 } 78 } 79} 80 81static void kill_tsr(void) 82{ 83 rb->queue_post(&queue, EV_EXIT, 0); 84 rb->thread_wait(thread_id); 85 rb->queue_delete(&queue); 86} 87 88static int exit_tsr(bool reenter) 89{ 90 MENUITEM_STRINGLIST(menu, "USB test menu", NULL, 91 "Status", "Stop plugin", "Back"); 92 93 while(true) { 94 int result = reenter ? rb->do_menu(&menu, NULL, NULL, false) : 1; 95 switch(result) { 96 case 0: 97 rb->splashf(HZ, "State: %s", state); 98 rb->splashf(HZ, "Prev: %s", prev_state); 99 break; 100 case 1: 101 rb->splashf(HZ, "Stopping USB test thread"); 102 kill_tsr(); 103 return (reenter ? PLUGIN_TSR_TERMINATE : PLUGIN_TSR_SUSPEND); 104 case 2: 105 return PLUGIN_TSR_CONTINUE; 106 } 107 } 108} 109 110static void run_tsr(void) 111{ 112 rb->queue_init(&queue, true); 113 thread_id = rb->create_thread(main_loop, stack, sizeof(stack), 114 0, "test_usb TSR" 115 IF_PRIO(, PRIORITY_BACKGROUND) 116 IF_COP(, CPU)); 117 rb->plugin_tsr(exit_tsr); 118} 119 120enum plugin_status plugin_start(const void* parameter) 121{ 122 bool resume = (parameter == rb->plugin_tsr); 123 124 MENUITEM_STRINGLIST(menu, "USB test menu", NULL, 125 "Start", "Quit"); 126 127 switch(!resume ? rb->do_menu(&menu, NULL, NULL, false) : 0) { 128 case 0: 129 run_tsr(); 130 rb->splashf(HZ, "USB test thread started"); 131 return PLUGIN_OK; 132 case 1: 133 return PLUGIN_OK; 134 default: 135 return PLUGIN_ERROR; 136 } 137}