A modern Music Player Daemon based on Rockbox open source high quality audio player
libadwaita audio rust zig deno mpris rockbox mpd
at master 322 lines 11 kB view raw
1/*************************************************************************** 2 * __________ __ ___. 3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___ 4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / 5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < 6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ 7 * \/ \/ \/ \/ \/ 8 * $Id$ 9 * 10 * Copyright (C) 2005 Michiel van der Kolk, Jens Arnold 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 "rockmacros.h" 23#include "fb.h" 24#include "input.h" 25#include "lcd-gb.h" 26#include "hw.h" 27#include "config.h" 28 29#if CONFIG_KEYPAD == SANSA_E200_PAD || CONFIG_KEYPAD == SANSA_FUZE_PAD 30#define ROCKBOY_SCROLLWHEEL 31#define ROCKBOY_SCROLLWHEEL_CC BUTTON_SCROLL_BACK 32#define ROCKBOY_SCROLLWHEEL_CW BUTTON_SCROLL_FWD 33#endif 34 35struct fb fb IBSS_ATTR; 36 37extern int debug_trace; 38 39#ifdef HAVE_WHEEL_POSITION 40static int oldwheel = -1, wheel; 41 42static int wheelmap[8] = { 43 PAD_UP, /* Top */ 44 PAD_A, /* Top-right */ 45 PAD_RIGHT, /* Right */ 46 PAD_START, /* Bottom-right */ 47 PAD_DOWN, /* Bottom */ 48 PAD_SELECT, /* Bottom-left */ 49 PAD_LEFT, /* Left */ 50 PAD_B /* Top-left */ 51}; 52#endif 53 54void ev_poll(void) 55{ 56 event_t ev; 57 58 static unsigned int oldbuttonstate; 59 unsigned int buttons = BUTTON_NONE; 60 unsigned int released, pressed; 61 unsigned int btn; 62 bool quit = false; 63 64 do 65 { 66 btn = rb->button_get(false); 67 /* BUTTON_NONE doesn't necessarily mean no button is pressed, 68 * it just means the button queue became empty for this tick. 69 * One can only be sure that no button is pressed by 70 * calling button_status(). */ 71 if (btn == BUTTON_NONE) 72 { 73 /* loop only until all button events are popped off */ 74 quit = true; 75 btn = rb->button_status(); 76 } 77 buttons |= btn; 78#if defined(HAVE_SCROLLWHEEL) && !defined(ROCKBOY_SCROLLWHEEL) 79 /* filter out scroll wheel events if not supported */ 80 buttons &= ~(BUTTON_SCROLL_FWD|BUTTON_SCROLL_BACK); 81#endif 82 } 83 while (!quit); 84 85 released = ~buttons & oldbuttonstate; 86 pressed = buttons & ~oldbuttonstate; 87 88 oldbuttonstate = buttons; 89#if (LCD_WIDTH == 160) && (LCD_HEIGHT == 128) && (LCD_DEPTH == 2) 90 static unsigned int holdbutton; 91 if (rb->button_hold()&~holdbutton) 92 fb.mode=(fb.mode+1)%4; 93 holdbutton=rb->button_hold(); 94#endif 95 96#ifdef HAVE_WHEEL_POSITION 97 /* Get the current wheel position - 0..95 or -1 for untouched */ 98 wheel = rb->wheel_status(); 99 100 /* Convert to number from 0 to 7 - clockwise from top */ 101 if ( wheel > 0 ){ 102 wheel += 6; 103 wheel /= 12; 104 if ( wheel > 7 ) wheel = 0; 105 } 106 107 if ( wheel != oldwheel ) { 108 if (oldwheel >= 0) { 109 ev.type = EV_RELEASE; 110 ev.code = wheelmap[oldwheel]; 111 ev_postevent(&ev); 112 } 113 114 if (wheel >= 0) { 115 ev.type = EV_PRESS; 116 ev.code = wheelmap[wheel]; 117 ev_postevent(&ev); 118 } 119 } 120 121 oldwheel = wheel; 122 if(released) { 123 ev.type = EV_RELEASE; 124 if ( released & (~BUTTON_SELECT) ) { ev.code=PAD_B; ev_postevent(&ev); } 125 if ( released & BUTTON_SELECT ) { ev.code=PAD_A; ev_postevent(&ev); } 126 } 127 if(pressed) { /* button press */ 128 ev.type = EV_PRESS; 129 if ( pressed & (~BUTTON_SELECT) ) { ev.code=PAD_B; ev_postevent(&ev); } 130 if ( pressed & BUTTON_SELECT ) { ev.code=PAD_A; ev_postevent(&ev); } 131 } 132#else 133 if(released) { 134 ev.type = EV_RELEASE; 135#ifdef HAVE_LCD_COLOR 136 if (options.rotate == 1) /* if screen is rotated, rotate direction keys */ 137 { 138 if(released & options.LEFT) {ev.code=PAD_DOWN; ev_postevent(&ev);} 139 if(released & options.RIGHT) {ev.code=PAD_UP; ev_postevent(&ev);} 140 if(released & options.DOWN) {ev.code=PAD_RIGHT; ev_postevent(&ev);} 141 if(released & options.UP) {ev.code=PAD_LEFT; ev_postevent(&ev);} 142 } 143 else if (options.rotate == 2) /* if screen is rotated, rotate direction keys */ 144 { 145 if(released & options.LEFT) {ev.code=PAD_UP; ev_postevent(&ev);} 146 if(released & options.RIGHT) {ev.code=PAD_DOWN; ev_postevent(&ev);} 147 if(released & options.DOWN) {ev.code=PAD_LEFT; ev_postevent(&ev);} 148 if(released & options.UP) {ev.code=PAD_RIGHT; ev_postevent(&ev);} 149 } 150 else /* screen is not rotated, do not rotate direction keys */ 151 { 152 if(released & options.LEFT) {ev.code=PAD_LEFT; ev_postevent(&ev);} 153 if(released & options.RIGHT) {ev.code=PAD_RIGHT; ev_postevent(&ev);} 154 if(released & options.DOWN) {ev.code=PAD_DOWN; ev_postevent(&ev);} 155 if(released & options.UP) {ev.code=PAD_UP; ev_postevent(&ev);} 156 } 157#else 158 if(released & options.LEFT) {ev.code=PAD_LEFT; ev_postevent(&ev);} 159 if(released & options.RIGHT) {ev.code=PAD_RIGHT; ev_postevent(&ev);} 160 if(released & options.DOWN) {ev.code=PAD_DOWN; ev_postevent(&ev);} 161 if(released & options.UP) {ev.code=PAD_UP; ev_postevent(&ev);} 162#endif 163 if(released & options.A) { ev.code=PAD_A; ev_postevent(&ev); } 164 if(released & options.B) { ev.code=PAD_B; ev_postevent(&ev); } 165 if(released & options.START) { 166 ev.code=PAD_START; 167 ev_postevent(&ev); 168 } 169 if(released & options.SELECT) { 170 ev.code=PAD_SELECT; 171 ev_postevent(&ev); 172 } 173 } 174 if(pressed) { /* button press */ 175 ev.type = EV_PRESS; 176#ifdef HAVE_LCD_COLOR 177 if (options.rotate == 1) /* if screen is rotated, rotate direction keys */ 178 { 179 if(pressed & options.LEFT) {ev.code=PAD_DOWN; ev_postevent(&ev);} 180 if(pressed & options.RIGHT) {ev.code=PAD_UP; ev_postevent(&ev);} 181 if(pressed & options.DOWN) {ev.code=PAD_RIGHT; ev_postevent(&ev);} 182 if(pressed & options.UP) {ev.code=PAD_LEFT; ev_postevent(&ev);} 183 } 184 else if (options.rotate == 2) /* if screen is rotated, rotate direction keys */ 185 { 186 if(pressed & options.LEFT) {ev.code=PAD_UP; ev_postevent(&ev);} 187 if(pressed & options.RIGHT) {ev.code=PAD_DOWN; ev_postevent(&ev);} 188 if(pressed & options.DOWN) {ev.code=PAD_LEFT; ev_postevent(&ev);} 189 if(pressed & options.UP) {ev.code=PAD_RIGHT; ev_postevent(&ev);} 190 } 191 else /* screen is not rotated, do not rotate direction keys */ 192 { 193 if(pressed & options.LEFT) {ev.code=PAD_LEFT; ev_postevent(&ev);} 194 if(pressed & options.RIGHT) {ev.code=PAD_RIGHT; ev_postevent(&ev);} 195 if(pressed & options.DOWN) {ev.code=PAD_DOWN; ev_postevent(&ev);} 196 if(pressed & options.UP) {ev.code=PAD_UP; ev_postevent(&ev);} 197 } 198#else 199 if(pressed & options.LEFT) {ev.code=PAD_LEFT; ev_postevent(&ev);} 200 if(pressed & options.RIGHT) {ev.code=PAD_RIGHT; ev_postevent(&ev);} 201 if(pressed & options.DOWN) {ev.code=PAD_DOWN; ev_postevent(&ev);} 202 if(pressed & options.UP) {ev.code=PAD_UP; ev_postevent(&ev);} 203#endif 204 if(pressed & options.A) { ev.code=PAD_A; ev_postevent(&ev); } 205 if(pressed & options.B) { ev.code=PAD_B; ev_postevent(&ev); } 206 if(pressed & options.START) { 207 ev.code=PAD_START; 208 ev_postevent(&ev); 209 } 210 if(pressed & options.SELECT) { 211 ev.code=PAD_SELECT; 212 ev_postevent(&ev); 213 } 214#endif 215#if CONFIG_KEYPAD == IPOD_4G_PAD 216 if(rb->button_hold()) { 217#else 218 if(pressed & options.MENU) { 219#endif 220#ifdef HAVE_WHEEL_POSITION 221 rb->wheel_send_events(true); 222#endif 223 if (do_user_menu() == USER_MENU_QUIT) 224 { 225 die(""); 226 cleanshut=1; 227 } 228#ifdef HAVE_WHEEL_POSITION 229 rb->wheel_send_events(false); 230#endif 231 } 232 233#ifndef HAVE_WHEEL_POSITION 234 } 235#endif 236} 237 238/* New frameskip, makes more sense to me and performs as well */ 239void vid_begin(void) 240{ 241 static int skip = 0; 242 if (skip<options.frameskip) 243 { 244 skip++; 245 fb.enabled=0; 246 } 247 else 248 { 249 skip=0; 250 fb.enabled=1; 251 } 252} 253 254void vid_init(void) 255{ 256 fb.enabled=1; 257 258#if !defined(HAVE_LCD_COLOR) 259 fb.mode=3; 260#endif 261} 262 263#if !defined(HAVE_LCD_COLOR) 264/* Color targets are handled in lcd.c */ 265fb_data *frameb; 266void vid_update(int scanline) 267{ 268 register int cnt=0; 269 static fb_data *lcd_fb = NULL; 270 if (!lcd_fb) 271 { 272 struct viewport *vp_main = *(rb->screens[SCREEN_MAIN]->current_viewport); 273 lcd_fb = vp_main->buffer->fb_ptr; 274 } 275 int scanline_remapped; 276#if (LCD_HEIGHT == 64) && (LCD_DEPTH == 1) /* Archos, Clip, m200v4 */ 277 int balance = 0; 278 if (fb.mode==1) 279 scanline-=16; 280 else if (fb.mode==2) 281 scanline-=8; 282 scanline_remapped = scanline / 16; 283 frameb = lcd_fb + scanline_remapped * LCD_WIDTH; 284 while (cnt < 160) { 285 balance += LCD_WIDTH; 286 if (balance > 0) 287 { 288 register unsigned scrbyte = 0; 289 if (scan.buf[0][cnt] & 0x02) scrbyte |= 0x01; 290 if (scan.buf[1][cnt] & 0x02) scrbyte |= 0x02; 291 if (scan.buf[2][cnt] & 0x02) scrbyte |= 0x04; 292 if (scan.buf[3][cnt] & 0x02) scrbyte |= 0x08; 293 if (scan.buf[4][cnt] & 0x02) scrbyte |= 0x10; 294 if (scan.buf[5][cnt] & 0x02) scrbyte |= 0x20; 295 if (scan.buf[6][cnt] & 0x02) scrbyte |= 0x40; 296 if (scan.buf[7][cnt] & 0x02) scrbyte |= 0x80; 297 *(frameb++) = scrbyte; 298 balance -= 160; 299 } 300 cnt ++; 301 } 302 rb->lcd_update_rect(0, (scanline/2) & ~7, LCD_WIDTH, 8); 303#elif (LCD_HEIGHT == 128) && (LCD_DEPTH == 2) /* iriver H1x0, Samsung YH920 */ 304 if (fb.mode==1) 305 scanline-=16; 306 else if (fb.mode==2) 307 scanline-=8; 308 scanline_remapped = scanline / 4; 309 frameb = lcd_fb + scanline_remapped * LCD_WIDTH; 310 while (cnt < 160) { 311 *(frameb++) = (scan.buf[0][cnt]&0x3) | 312 ((scan.buf[1][cnt]&0x3)<<2) | 313 ((scan.buf[2][cnt]&0x3)<<4) | 314 ((scan.buf[3][cnt]&0x3)<<6); 315 cnt++; 316 } 317 rb->lcd_update_rect(0, scanline & ~3, LCD_WIDTH, 4); 318#elif defined(HAVE_LCD_COLOR) 319 /* handled in lcd.c now */ 320#endif /* LCD_HEIGHT */ 321} 322#endif