/* Caller isn't expected to filter for changes in status. * current_status: * USB_DETECT_BY_DRV: USB_POWERED, USB_UNPOWERED, USB_INSERTED (driver) * else: USB_INSERTED, USB_EXTRACTED */ if(usb_monitor_enabled) { int oldstatus = disable_irq_save(); /* Dual-use function */ if(last_usb_status != current_status) { last_usb_status = current_status; queue_post(&usb_queue, current_status, 0); } restore_irq(oldstatus); } } void usb_start_monitoring(void) { int oldstatus = disable_irq_save(); /* Sync to event */ int status = usb_detect(); usb_monitor_enabled = true; #ifdef USB_DETECT_BY_DRV status = (status == USB_INSERTED) ? USB_POWERED : USB_UNPOWERED; #endif usb_status_event(status); #ifdef USB_FIREWIRE_HANDLING if (firewire_detect()) usb_firewire_connect_event(); #endif restore_irq(oldstatus); } #ifdef USB_FIREWIRE_HANDLING void usb_firewire_connect_event(void) { queue_post(&usb_queue, USB_REQUEST_REBOOT, 0); } #endif /* USB_FIREWIRE_HANDLING */ #else /* !USB_STATUS_BY_EVENT */ static void usb_tick(void) { int current_status; if(usb_monitor_enabled) { #ifdef USB_FIREWIRE_HANDLING int current_firewire_status = firewire_detect(); if(current_firewire_status != last_firewire_status) { last_firewire_status = current_firewire_status; firewire_countdown = NUM_POLL_READINGS; } else { /* Count down until it gets negative */ if(firewire_countdown >= 0) firewire_countdown--; /* Report to the thread if we have had 3 identical status readings in a row */ if(firewire_countdown == 0) { queue_post(&usb_queue, USB_REQUEST_REBOOT, 0); } } #endif /* USB_FIREWIRE_HANDLING */ current_status = usb_detect(); /* Only report when the status has changed */ if(current_status != last_usb_status) { last_usb_status = current_status; countdown = NUM_POLL_READINGS; } else { /* Count down until it gets negative */ if(countdown >= 0) countdown--; /* Report to the thread if we have had 3 identical status readings in a row */ if(countdown == 0) { queue_post(&usb_queue, current_status, 0); } } } #if (CONFIG_STORAGE & STORAGE_MMC) if(usb_mmc_countdown > 0) { usb_mmc_countdown--; if (usb_mmc_countdown == 0) queue_post(&usb_queue, USB_REENABLE, 0); } #endif }
void sim_trigger_usb(bool inserted) { if (inserted) queue_post(&sim_queue, SIM_USB_INSERTED, 0); else queue_post(&sim_queue, SIM_USB_EXTRACTED, 0); is_usb_inserted = inserted; }
void t1(void) { debugf("Thread 1 started\n"); while(1) { sleep(HZ); debugf("Thread 1 posting an event\n"); queue_post(&main_q, 1234, 0); queue_post(&main_q, 5678, 0); } }
static bool button_try_post(int button, int data) { #ifdef HAVE_TOUCHSCREEN /* one can swipe over the scren very quickly, * for this to work we want to forget about old presses and * only respect the very latest ones */ const bool force_post = true; #else /* Only post events if the queue is empty, * to avoid afterscroll effects. * i.e. don't post new buttons if previous ones haven't been * processed yet - but always post releases */ const bool force_post = button & BUTTON_REL; #endif bool ret = queue_empty(&button_queue); if (!ret && force_post) { queue_remove_from_head(&button_queue, button); ret = true; } if (ret) queue_post(&button_queue, button, data); /* on touchscreen we posted unconditionally */ return ret; }
static void backlight_lcd_sleep_countdown(bool start) { if (!start) { /* Cancel the LCD sleep countdown */ lcd_sleep_timer = 0; return; } /* Start LCD sleep countdown */ if (lcd_sleep_timeout < 0) { lcd_sleep_timer = 0; /* Setting == Always */ /* Ensure lcd_sleep() is called from backlight_thread() */ #if (CONFIG_BACKLIGHT_FADING == BACKLIGHT_FADING_PWM) queue_post(&backlight_queue, LCD_SLEEP, 0); #else lcd_sleep(); #endif } else { lcd_sleep_timer = lcd_sleep_timeout; } }
/* This callback can be used for many different functions if needed - just check to which object tmo points */ static int btn_detect_callback(struct timeout *tmo) { /* Try to post only transistions */ const long id = tmo->data ? SYS_PHONE_PLUGGED : SYS_PHONE_UNPLUGGED; queue_remove_from_head(&button_queue, id); queue_post(&button_queue, id, 0); return 0; }
static void mpr121_irq_cb(int bank, int pin, intptr_t user) { (void) bank; (void) pin; (void) user; /* the callback will not be fired until interrupt is enabled back so * the queue will not overflow or contain multiple MPR121_INTERRUPT events */ queue_post(&mpr121_queue, MPR121_INTERRUPT, 0); }
void do_sbs_update_callback(void *param) { (void)param; /* the WPS handles changing the actual id3 data in the id3 pointers * we imported, we just want a full update */ skin_request_full_update(CUSTOM_STATUSBAR); /* force timeout in wps main loop, so that the update is instantly */ queue_post(&button_queue, BUTTON_NONE, 0); }
void thread_b(void) { int b = 1; printk("starting thread B\n"); while (1) { printk("[B] posting from queue: "); queue_post(&queue, &b, 1000); printk("%d\n", b); b++; } }
void usb_close(void) { unsigned int thread = usb_thread_entry; usb_thread_entry = 0; if (thread == 0) return; #ifndef USB_STATUS_BY_EVENT tick_remove_task(usb_tick); #endif usb_monitor_enabled = false; queue_post(&usb_queue, USB_QUIT, 0); thread_wait(thread); }
/* Handle Q_CODEC_SEEK */ static void seek_codec(unsigned long time) { if (codec_type == AFMT_UNKNOWN) { logf("no codec to seek"); codec_queue_ack(Q_CODEC_SEEK); codec_seek_complete_callback(); return; } /* Post it up one level */ queue_post(&codec_queue, Q_CODEC_SEEK, time); codec_queue_ack(Q_CODEC_SEEK); /* Have to run it again */ run_codec(); }
void usb_status_event(int current_status) { /* Caller isn't expected to filter for changes in status. * current_status: * USB_DETECT_BY_DRV: USB_POWERED, USB_UNPOWERED, USB_INSERTED (driver) * else: USB_INSERTED, USB_EXTRACTED */ if(usb_monitor_enabled) { int oldstatus = disable_irq_save(); /* Dual-use function */ if(last_usb_status != current_status) { last_usb_status = current_status; queue_post(&usb_queue, current_status, 0); } restore_irq(oldstatus); } }
static int kinetic_callback(struct timeout *tmo) { /* cancel if screen was pressed */ if (scroll_mode != SCROLL_KINETIC) return 0; struct cb_data *data = (struct cb_data*)tmo->data; int line_height = font_get(data->list->parent[0]->font)->height; /* ds = v*dt */ int pixel_diff = data->velocity * RELOAD_INTERVAL / HZ; /* remember signedness to detect stopping */ int old_sign = SIGN(data->velocity); /* advance the list */ if (!swipe_scroll(data->list, line_height, pixel_diff)) { /* nothing to scroll? */ data->velocity = 0; } else { /* decelerate by a fixed amount * decrementing v0 over time by the deceleration is * equivalent to computing v = a*t + v0 */ data->velocity -= SIGN(data->velocity)*DECELERATION; if (SIGN(data->velocity) != old_sign) data->velocity = 0; } queue_post(&button_queue, BUTTON_TOUCHSCREEN, 0); /* stop if the velocity hit or crossed zero */ if (!data->velocity) { kinetic_stats_reset(); return 0; } /* let get_action() timeout, which loads to a * gui_synclist_draw() call from the main thread */ return RELOAD_INTERVAL; /* cancel or reload */ }
void buttonlight_off(void) { queue_post(&backlight_queue, BUTTON_LIGHT_OFF, 0); }
/* external interface */ void buttonlight_on(void) { queue_remove_from_head(&backlight_queue, BUTTON_LIGHT_ON); queue_post(&backlight_queue, BUTTON_LIGHT_ON, 0); }
/* Reserve space in the buffer for a file. filename: name of the file to open offset: offset at which to start buffering the file, useful when the first (offset-1) bytes of the file aren't needed. type: one of the data types supported (audio, image, cuesheet, others user_data: user data passed possibly passed in subcalls specific to a data_type (only used for image (albumart) buffering so far ) return value: <0 if the file cannot be opened, or one file already queued to be opened, otherwise the handle for the file in the buffer */ int bufopen(const char *file, size_t offset, enum data_type type, void *user_data) { #ifndef HAVE_ALBUMART /* currently only used for aa loading */ (void)user_data; #endif if (type == TYPE_ID3) { /* ID3 case: allocate space, init the handle and return. */ struct memory_handle *h = add_handle(sizeof(struct mp3entry), false, true); if (!h) return ERR_BUFFER_FULL; h->fd = -1; h->filesize = sizeof(struct mp3entry); h->filerem = sizeof(struct mp3entry); h->offset = 0; h->data = buf_widx; h->ridx = buf_widx; h->widx = buf_widx; h->available = 0; h->type = type; strlcpy(h->path, file, MAX_PATH); buf_widx += sizeof(struct mp3entry); /* safe because the handle can't wrap */ /* Inform the buffering thread that we added a handle */ LOGFQUEUE("buffering > Q_HANDLE_ADDED %d", h->id); queue_post(&buffering_queue, Q_HANDLE_ADDED, h->id); return h->id; } /* Other cases: there is a little more work. */ int fd = open(file, O_RDONLY); if (fd < 0) return ERR_FILE_ERROR; size_t size = filesize(fd); bool can_wrap = type==TYPE_PACKET_AUDIO || type==TYPE_CODEC; size_t adjusted_offset = offset; if (adjusted_offset > size) adjusted_offset = 0; /* Reserve extra space because alignment can move data forward */ size_t padded_size = STORAGE_PAD(size-adjusted_offset); struct memory_handle *h = add_handle(padded_size, can_wrap, false); if (!h) { DEBUGF("%s(): failed to add handle\n", __func__); close(fd); return ERR_BUFFER_FULL; } strlcpy(h->path, file, MAX_PATH); h->offset = adjusted_offset; /* Don't bother to storage align bitmaps because they are not * loaded directly into the buffer. */ if (type != TYPE_BITMAP) { size_t alignment_pad; /* Remember where data area starts, for use by reset_handle */ h->start = buf_widx; /* Align to desired storage alignment */ alignment_pad = STORAGE_OVERLAP(adjusted_offset - (size_t)(&buffer[buf_widx])); buf_widx = ringbuf_add(buf_widx, alignment_pad); } h->ridx = buf_widx; h->widx = buf_widx; h->data = buf_widx; h->available = 0; h->filerem = 0; h->type = type; #ifdef HAVE_ALBUMART if (type == TYPE_BITMAP) { /* Bitmap file: we load the data instead of the file */ int rc; mutex_lock(&llist_mod_mutex); /* Lock because load_bitmap yields */ rc = load_image(fd, file, (struct dim*)user_data); mutex_unlock(&llist_mod_mutex); if (rc <= 0) { rm_handle(h); close(fd); return ERR_FILE_ERROR; } h->filerem = 0; h->filesize = rc; h->available = rc; h->widx = buf_widx + rc; /* safe because the data doesn't wrap */ buf_widx += rc; /* safe too */ } else #endif { h->filerem = size - adjusted_offset; h->filesize = size; h->available = 0; h->widx = buf_widx; } if (type == TYPE_CUESHEET) { h->fd = fd; /* Immediately start buffering those */ LOGFQUEUE("buffering >| Q_BUFFER_HANDLE %d", h->id); queue_send(&buffering_queue, Q_BUFFER_HANDLE, h->id); } else { /* Other types will get buffered in the course of normal operations */ h->fd = -1; close(fd); /* Inform the buffering thread that we added a handle */ LOGFQUEUE("buffering > Q_HANDLE_ADDED %d", h->id); queue_post(&buffering_queue, Q_HANDLE_ADDED, h->id); } logf("bufopen: new hdl %d", h->id); return h->id; }
static void pmu_eint_isr(struct eint_handler *h) { eint_unregister(h); queue_post(&pmu_queue, Q_EINT, 0); }
void usb_charger_update(void) { queue_post(&usb_queue, USB_CHARGER_UPDATE, 0); }
void audio_queue_post(long id, intptr_t data) { queue_post(&audio_queue, id, data); }
void usb_firewire_connect_event(void) { queue_post(&usb_queue, USB_REQUEST_REBOOT, 0); }
/** CODEC THREAD */ static void codec_thread(void) { struct queue_event ev; int status; while (1) { status = 0; #ifdef HAVE_CROSSFADE if (!pcmbuf_is_crossfade_active()) #endif { cancel_cpu_boost(); } queue_wait(&codec_queue, &ev); codec_requested_stop = false; switch (ev.id) { case Q_CODEC_LOAD_DISK: LOGFQUEUE("codec < Q_CODEC_LOAD_DISK"); queue_reply(&codec_queue, 1); audio_codec_loaded = true; ci.stop_codec = false; status = codec_load_file((const char *)ev.data, &ci); LOGFQUEUE("codec_load_file %s %d\n", (const char *)ev.data, status); break; case Q_CODEC_LOAD: LOGFQUEUE("codec < Q_CODEC_LOAD"); if (*get_codec_hid() < 0) { logf("Codec slot is empty!"); /* Wait for the pcm buffer to go empty */ while (pcm_is_playing()) yield(); /* This must be set to prevent an infinite loop */ ci.stop_codec = true; LOGFQUEUE("codec > codec Q_AUDIO_PLAY"); queue_post(&codec_queue, Q_AUDIO_PLAY, 0); break; } audio_codec_loaded = true; ci.stop_codec = false; status = codec_load_buf(*get_codec_hid(), &ci); LOGFQUEUE("codec_load_buf %d\n", status); break; case Q_CODEC_DO_CALLBACK: LOGFQUEUE("codec < Q_CODEC_DO_CALLBACK"); queue_reply(&codec_queue, 1); if ((void*)ev.data != NULL) { cpucache_invalidate(); ((void (*)(void))ev.data)(); cpucache_flush(); } break; #ifdef AUDIO_HAVE_RECORDING case Q_ENCODER_LOAD_DISK: LOGFQUEUE("codec < Q_ENCODER_LOAD_DISK"); audio_codec_loaded = false; /* Not audio codec! */ logf("loading encoder"); ci.stop_encoder = false; status = codec_load_file((const char *)ev.data, &ci); logf("encoder stopped"); break; #endif /* AUDIO_HAVE_RECORDING */ default: LOGFQUEUE("codec < default"); } if (audio_codec_loaded) { if (ci.stop_codec) { status = CODEC_OK; if (!(audio_status() & AUDIO_STATUS_PLAY)) pcmbuf_play_stop(); } audio_codec_loaded = false; } switch (ev.id) { case Q_CODEC_LOAD_DISK: case Q_CODEC_LOAD: LOGFQUEUE("codec < Q_CODEC_LOAD"); if (audio_status() & AUDIO_STATUS_PLAY) { if (ci.new_track || status != CODEC_OK) { if (!ci.new_track) { logf("Codec failure, %d %d", ci.new_track, status); splash(HZ*2, "Codec failure"); } if (!codec_load_next_track()) { LOGFQUEUE("codec > audio Q_AUDIO_STOP"); /* End of playlist */ queue_post(&audio_queue, Q_AUDIO_STOP, 0); break; } } else { logf("Codec finished"); if (ci.stop_codec) { /* Wait for the audio to stop playing before * triggering the WPS exit */ while(pcm_is_playing()) { /* There has been one too many struct pointer swaps by now * so even though it says othertrack_id3, its the correct one! */ othertrack_id3->elapsed = othertrack_id3->length - pcmbuf_get_latency(); sleep(1); } if (codec_requested_stop) { LOGFQUEUE("codec > audio Q_AUDIO_STOP"); queue_post(&audio_queue, Q_AUDIO_STOP, 0); } break; } } if (*get_codec_hid() >= 0) { LOGFQUEUE("codec > codec Q_CODEC_LOAD"); queue_post(&codec_queue, Q_CODEC_LOAD, 0); } else { const char *codec_fn = get_codec_filename(thistrack_id3->codectype); if (codec_fn) { LOGFQUEUE("codec > codec Q_CODEC_LOAD_DISK"); queue_post(&codec_queue, Q_CODEC_LOAD_DISK, (intptr_t)codec_fn); } } } break; #ifdef AUDIO_HAVE_RECORDING case Q_ENCODER_LOAD_DISK: LOGFQUEUE("codec < Q_ENCODER_LOAD_DISK"); if (status == CODEC_OK) break; logf("Encoder failure"); splash(HZ*2, "Encoder failure"); if (ci.enc_codec_loaded < 0) break; logf("Encoder failed to load"); ci.enc_codec_loaded = -1; break; #endif /* AUDIO_HAVE_RECORDING */ default: LOGFQUEUE("codec < default"); } /* end switch */ } }
static void button_event(int key, bool pressed) { int new_btn = 0; static bool usb_connected = false; if (usb_connected && key != USB_KEY) return; switch (key) { case USB_KEY: if (!pressed) { usb_connected = !usb_connected; if (usb_connected) queue_post(&button_queue, SYS_USB_CONNECTED, 0); else queue_post(&button_queue, SYS_USB_DISCONNECTED, 0); } return; #if (CONFIG_PLATFORM & PLATFORM_PANDORA) case SDLK_LCTRL: /* Will post SDL_USEREVENT in shutdown_hw() if successful. */ sys_poweroff(); break; #endif #ifdef HAS_BUTTON_HOLD case SDLK_h: if(pressed) { hold_button_state = !hold_button_state; DEBUGF("Hold button is %s\n", hold_button_state?"ON":"OFF"); } return; #endif #ifdef HAS_REMOTE_BUTTON_HOLD case SDLK_j: if(pressed) { remote_hold_button_state = !remote_hold_button_state; DEBUGF("Remote hold button is %s\n", remote_hold_button_state?"ON":"OFF"); } return; #endif #if defined(IRIVER_H100_SERIES) || defined (IRIVER_H300_SERIES) case SDLK_t: if(pressed) switch(_remote_type) { case REMOTETYPE_UNPLUGGED: _remote_type=REMOTETYPE_H100_LCD; DEBUGF("Changed remote type to H100\n"); break; case REMOTETYPE_H100_LCD: _remote_type=REMOTETYPE_H300_LCD; DEBUGF("Changed remote type to H300\n"); break; case REMOTETYPE_H300_LCD: _remote_type=REMOTETYPE_H300_NONLCD; DEBUGF("Changed remote type to H300 NON-LCD\n"); break; case REMOTETYPE_H300_NONLCD: _remote_type=REMOTETYPE_UNPLUGGED; DEBUGF("Changed remote type to none\n"); break; } break; #endif case SDLK_KP0: case SDLK_F5: if(pressed) { sim_trigger_screendump(); return; } break; #ifdef HAVE_TOUCHSCREEN case SDLK_F4: if(pressed) { touchscreen_set_mode(touchscreen_get_mode() == TOUCHSCREEN_POINT ? TOUCHSCREEN_BUTTON : TOUCHSCREEN_POINT); printf("Touchscreen mode: %s\n", touchscreen_get_mode() == TOUCHSCREEN_POINT ? "TOUCHSCREEN_POINT" : "TOUCHSCREEN_BUTTON"); } #endif default: #ifdef HAVE_TOUCHSCREEN new_btn = key_to_touch(key, mouse_coords); if (!new_btn) #endif new_btn = key_to_button(key); break; } /* Call to make up for scrollwheel target implementation. This is * not handled in the main button.c driver, but on the target * implementation (look at button-e200.c for example if you are trying to * figure out why using button_get_data needed a hack before). */ #if defined(BUTTON_SCROLL_FWD) && defined(BUTTON_SCROLL_BACK) if((new_btn == BUTTON_SCROLL_FWD || new_btn == BUTTON_SCROLL_BACK) && pressed) { /* Clear these buttons from the data - adding them to the queue is * handled in the scrollwheel drivers for the targets. They do not * store the scroll forward/back buttons in their button data for * the button_read call. */ #ifdef HAVE_BACKLIGHT backlight_on(); #endif #ifdef HAVE_BUTTON_LIGHT buttonlight_on(); #endif queue_post(&button_queue, new_btn, 1<<24); new_btn &= ~(BUTTON_SCROLL_FWD | BUTTON_SCROLL_BACK); } #endif if (pressed) btn |= new_btn; else btn &= ~new_btn; }
void buttonlight_set_timeout(int value) { buttonlight_timeout = HZ * value; queue_post(&backlight_queue, BUTTON_LIGHT_TMO_CHANGED, 0); }
void button_event(int key, bool pressed) { int new_btn = 0; static bool usb_connected = false; if (usb_connected && key != SDLK_u) return; switch (key) { #ifdef HAVE_TOUCHSCREEN case BUTTON_TOUCHSCREEN: switch (touchscreen_get_mode()) { case TOUCHSCREEN_POINT: new_btn = BUTTON_TOUCHSCREEN; break; case TOUCHSCREEN_BUTTON: { static int touchscreen_buttons[3][3] = { {BUTTON_TOPLEFT, BUTTON_TOPMIDDLE, BUTTON_TOPRIGHT}, {BUTTON_MIDLEFT, BUTTON_CENTER, BUTTON_MIDRIGHT}, {BUTTON_BOTTOMLEFT, BUTTON_BOTTOMMIDDLE, BUTTON_BOTTOMRIGHT}, }; int px_x = ((mouse_coords&0xffff0000)>>16); int px_y = ((mouse_coords&0x0000ffff)); new_btn = touchscreen_buttons[px_y/(LCD_HEIGHT/3)][px_x/(LCD_WIDTH/3)]; break; } } break; case SDLK_KP7: new_btn = BUTTON_TOPLEFT; break; case SDLK_KP8: new_btn = BUTTON_TOPMIDDLE; break; case SDLK_KP9: new_btn = BUTTON_TOPRIGHT; break; case SDLK_KP4: new_btn = BUTTON_MIDLEFT; break; case SDLK_KP5: new_btn = BUTTON_CENTER; break; case SDLK_KP6: new_btn = BUTTON_MIDRIGHT; break; case SDLK_KP1: new_btn = BUTTON_BOTTOMLEFT; break; case SDLK_KP2: new_btn = BUTTON_BOTTOMMIDDLE; break; case SDLK_KP3: new_btn = BUTTON_BOTTOMRIGHT; break; case SDLK_F4: if(pressed) { touchscreen_set_mode(touchscreen_get_mode() == TOUCHSCREEN_POINT ? TOUCHSCREEN_BUTTON : TOUCHSCREEN_POINT); printf("Touchscreen mode: %s\n", touchscreen_get_mode() == TOUCHSCREEN_POINT ? "TOUCHSCREEN_POINT" : "TOUCHSCREEN_BUTTON"); } break; #endif case SDLK_u: if (!pressed) { usb_connected = !usb_connected; if (usb_connected) queue_post(&button_queue, SYS_USB_CONNECTED, 0); else queue_post(&button_queue, SYS_USB_DISCONNECTED, 0); } return; #ifdef HAS_BUTTON_HOLD case SDLK_h: if(pressed) { hold_button_state = !hold_button_state; DEBUGF("Hold button is %s\n", hold_button_state?"ON":"OFF"); } return; #endif #ifdef HAS_REMOTE_BUTTON_HOLD case SDLK_j: if(pressed) { remote_hold_button_state = !remote_hold_button_state; DEBUGF("Remote hold button is %s\n", remote_hold_button_state?"ON":"OFF"); } return; #endif #if CONFIG_KEYPAD == GIGABEAT_PAD case SDLK_KP4: case SDLK_LEFT: new_btn = BUTTON_LEFT; break; case SDLK_KP6: case SDLK_RIGHT: new_btn = BUTTON_RIGHT; break; case SDLK_KP8: case SDLK_UP: new_btn = BUTTON_UP; break; case SDLK_KP2: case SDLK_DOWN: new_btn = BUTTON_DOWN; break; case SDLK_KP_PLUS: case SDLK_F8: new_btn = BUTTON_POWER; break; case SDLK_ESCAPE: new_btn = BUTTON_POWER; break; case SDLK_KP_ENTER: case SDLK_RETURN: case SDLK_a: new_btn = BUTTON_A; break; case SDLK_KP5: case SDLK_SPACE: new_btn = BUTTON_SELECT; break; case SDLK_KP_PERIOD: case SDLK_INSERT: new_btn = BUTTON_MENU; break; case SDLK_KP9: new_btn = BUTTON_VOL_UP; break; case SDLK_KP3: new_btn = BUTTON_VOL_DOWN; break; #elif CONFIG_KEYPAD == GIGABEAT_S_PAD case SDLK_KP4: case SDLK_LEFT: new_btn = BUTTON_LEFT; break; case SDLK_KP6: case SDLK_RIGHT: new_btn = BUTTON_RIGHT; break; case SDLK_KP8: case SDLK_UP: new_btn = BUTTON_UP; break; case SDLK_KP2: case SDLK_DOWN: new_btn = BUTTON_DOWN; break; case SDLK_F8: case SDLK_ESCAPE: new_btn = BUTTON_POWER; break; case SDLK_KP_PLUS: case SDLK_KP_ENTER: case SDLK_RETURN: new_btn = BUTTON_PLAY; break; case SDLK_KP7: new_btn = BUTTON_BACK; break; case SDLK_KP5: case SDLK_SPACE: new_btn = BUTTON_SELECT; break; case SDLK_KP9: case SDLK_KP_PERIOD: case SDLK_INSERT: new_btn = BUTTON_MENU; break; #elif CONFIG_KEYPAD == IAUDIO_X5M5_PAD case SDLK_KP4: case SDLK_LEFT: new_btn = BUTTON_LEFT; break; case SDLK_KP6: case SDLK_RIGHT: new_btn = BUTTON_RIGHT; break; case SDLK_KP8: case SDLK_UP: new_btn = BUTTON_UP; break; case SDLK_KP2: case SDLK_DOWN: new_btn = BUTTON_DOWN; break; case SDLK_KP_PLUS: case SDLK_F8: new_btn = BUTTON_PLAY; break; case SDLK_ESCAPE: new_btn = BUTTON_POWER; break; case SDLK_KP_ENTER: case SDLK_RETURN: case SDLK_a: new_btn = BUTTON_POWER; break; case SDLK_KP_DIVIDE: case SDLK_F1: new_btn = BUTTON_REC; break; case SDLK_KP5: case SDLK_SPACE: new_btn = BUTTON_SELECT; break; #elif CONFIG_KEYPAD == IAUDIO_M3_PAD case SDLK_KP4: case SDLK_LEFT: new_btn = BUTTON_LEFT; break; case SDLK_KP6: case SDLK_RIGHT: new_btn = BUTTON_RIGHT; break; case SDLK_KP8: case SDLK_UP: new_btn = BUTTON_VOL_UP; break; case SDLK_KP2: case SDLK_DOWN: new_btn = BUTTON_VOL_DOWN; break; case SDLK_KP_PERIOD: case SDLK_INSERT: new_btn = BUTTON_MODE; break; case SDLK_KP_DIVIDE: case SDLK_F1: new_btn = BUTTON_REC; break; case SDLK_KP5: case SDLK_SPACE: new_btn = BUTTON_PLAY; break; #elif (CONFIG_KEYPAD == IPOD_1G2G_PAD) || (CONFIG_KEYPAD == IPOD_3G_PAD) \ || (CONFIG_KEYPAD == IPOD_4G_PAD) case SDLK_KP4: case SDLK_LEFT: new_btn = BUTTON_LEFT; break; case SDLK_KP6: case SDLK_RIGHT: new_btn = BUTTON_RIGHT; break; case SDLK_KP8: case SDLK_UP: new_btn = BUTTON_SCROLL_BACK; break; case SDLK_KP2: case SDLK_DOWN: new_btn = BUTTON_SCROLL_FWD; break; case SDLK_KP_PLUS: case SDLK_F8: new_btn = BUTTON_PLAY; break; case SDLK_KP5: case SDLK_SPACE: new_btn = BUTTON_SELECT; break; case SDLK_KP_PERIOD: case SDLK_INSERT: new_btn = BUTTON_MENU; break; #elif CONFIG_KEYPAD == IRIVER_H10_PAD case SDLK_KP4: case SDLK_LEFT: new_btn = BUTTON_LEFT; break; case SDLK_KP6: case SDLK_RIGHT: new_btn = BUTTON_RIGHT; break; case SDLK_KP8: case SDLK_UP: new_btn = BUTTON_SCROLL_UP; break; case SDLK_KP2: case SDLK_DOWN: new_btn = BUTTON_SCROLL_DOWN; break; case SDLK_KP_PLUS: case SDLK_F8: new_btn = BUTTON_POWER; break; case SDLK_ESCAPE: new_btn = BUTTON_POWER; break; case SDLK_KP_DIVIDE: case SDLK_F1: new_btn = BUTTON_REW; break; case SDLK_KP_MULTIPLY: case SDLK_F2: new_btn = BUTTON_FF; break; case SDLK_KP5: case SDLK_SPACE: new_btn = BUTTON_PLAY; break; #elif (CONFIG_KEYPAD == IRIVER_H100_PAD) || (CONFIG_KEYPAD == IRIVER_H300_PAD) case SDLK_t: if(pressed) switch(_remote_type) { case REMOTETYPE_UNPLUGGED: _remote_type=REMOTETYPE_H100_LCD; DEBUGF("Changed remote type to H100\n"); break; case REMOTETYPE_H100_LCD: _remote_type=REMOTETYPE_H300_LCD; DEBUGF("Changed remote type to H300\n"); break; case REMOTETYPE_H300_LCD: _remote_type=REMOTETYPE_H300_NONLCD; DEBUGF("Changed remote type to H300 NON-LCD\n"); break; case REMOTETYPE_H300_NONLCD: _remote_type=REMOTETYPE_UNPLUGGED; DEBUGF("Changed remote type to none\n"); break; } break; case SDLK_KP4: case SDLK_LEFT: new_btn = BUTTON_LEFT; break; case SDLK_KP6: case SDLK_RIGHT: new_btn = BUTTON_RIGHT; break; case SDLK_KP8: case SDLK_UP: new_btn = BUTTON_UP; break; case SDLK_KP2: case SDLK_DOWN: new_btn = BUTTON_DOWN; break; case SDLK_KP_PLUS: case SDLK_F8: new_btn = BUTTON_ON; break; case SDLK_KP_ENTER: case SDLK_RETURN: case SDLK_a: new_btn = BUTTON_OFF; break; case SDLK_KP_DIVIDE: case SDLK_F1: new_btn = BUTTON_REC; break; case SDLK_KP5: case SDLK_SPACE: new_btn = BUTTON_SELECT; break; case SDLK_KP_PERIOD: case SDLK_INSERT: new_btn = BUTTON_MODE; break; #elif CONFIG_KEYPAD == IRIVER_IFP7XX_PAD case SDLK_KP4: case SDLK_LEFT: new_btn = BUTTON_LEFT; break; case SDLK_KP6: case SDLK_RIGHT: new_btn = BUTTON_RIGHT; break; case SDLK_KP8: case SDLK_UP: new_btn = BUTTON_UP; break; case SDLK_KP2: case SDLK_DOWN: new_btn = BUTTON_DOWN; break; case SDLK_KP_PLUS: case SDLK_F8: new_btn = BUTTON_PLAY; break; case SDLK_KP_ENTER: case SDLK_RETURN: case SDLK_a: new_btn = BUTTON_EQ; break; case SDLK_KP5: case SDLK_SPACE: new_btn = BUTTON_SELECT; break; case SDLK_KP_PERIOD: case SDLK_INSERT: new_btn = BUTTON_MODE; break; #elif CONFIG_KEYPAD == ONDIO_PAD case SDLK_KP4: case SDLK_LEFT: new_btn = BUTTON_LEFT; break; case SDLK_KP6: case SDLK_RIGHT: new_btn = BUTTON_RIGHT; break; case SDLK_KP8: case SDLK_UP: new_btn = BUTTON_UP; break; case SDLK_KP2: case SDLK_DOWN: new_btn = BUTTON_DOWN; break; case SDLK_KP_ENTER: case SDLK_RETURN: case SDLK_a: new_btn = BUTTON_OFF; break; case SDLK_KP_PERIOD: case SDLK_INSERT: new_btn = BUTTON_MENU; break; #elif CONFIG_KEYPAD == PLAYER_PAD case SDLK_KP4: case SDLK_LEFT: new_btn = BUTTON_LEFT; break; case SDLK_KP6: case SDLK_RIGHT: new_btn = BUTTON_RIGHT; break; case SDLK_KP8: case SDLK_UP: new_btn = BUTTON_PLAY; break; case SDLK_KP2: case SDLK_DOWN: new_btn = BUTTON_STOP; break; case SDLK_KP_PLUS: case SDLK_F8: new_btn = BUTTON_ON; break; case SDLK_KP_PERIOD: case SDLK_INSERT: new_btn = BUTTON_MENU; break; #elif CONFIG_KEYPAD == RECORDER_PAD case SDLK_KP4: case SDLK_LEFT: new_btn = BUTTON_LEFT; break; case SDLK_KP6: case SDLK_RIGHT: new_btn = BUTTON_RIGHT; break; case SDLK_KP8: case SDLK_UP: new_btn = BUTTON_UP; break; case SDLK_KP2: case SDLK_DOWN: new_btn = BUTTON_DOWN; break; case SDLK_KP_PLUS: case SDLK_F8: new_btn = BUTTON_ON; break; case SDLK_KP_ENTER: case SDLK_RETURN: case SDLK_a: new_btn = BUTTON_OFF; break; case SDLK_KP_DIVIDE: case SDLK_F1: new_btn = BUTTON_F1; break; case SDLK_KP_MULTIPLY: case SDLK_F2: new_btn = BUTTON_F2; break; case SDLK_KP_MINUS: case SDLK_F3: new_btn = BUTTON_F3; break; case SDLK_KP5: case SDLK_SPACE: new_btn = BUTTON_PLAY; break; #elif CONFIG_KEYPAD == ARCHOS_AV300_PAD case SDLK_KP4: case SDLK_LEFT: new_btn = BUTTON_LEFT; break; case SDLK_KP6: case SDLK_RIGHT: new_btn = BUTTON_RIGHT; break; case SDLK_KP8: case SDLK_UP: new_btn = BUTTON_UP; break; case SDLK_KP2: case SDLK_DOWN: new_btn = BUTTON_DOWN; break; case SDLK_KP_PLUS: case SDLK_F8: new_btn = BUTTON_ON; break; case SDLK_KP_ENTER: case SDLK_RETURN: case SDLK_a: new_btn = BUTTON_OFF; break; case SDLK_KP_DIVIDE: case SDLK_F1: new_btn = BUTTON_F1; break; case SDLK_KP_MULTIPLY: case SDLK_F2: new_btn = BUTTON_F2; break; case SDLK_KP_MINUS: case SDLK_F3: new_btn = BUTTON_F3; break; case SDLK_KP5: case SDLK_SPACE: new_btn = BUTTON_SELECT; break; #elif CONFIG_KEYPAD == SANSA_E200_PAD case SDLK_KP4: case SDLK_LEFT: new_btn = BUTTON_LEFT; break; case SDLK_KP6: case SDLK_RIGHT: new_btn = BUTTON_RIGHT; break; case SDLK_KP8: case SDLK_UP: new_btn = BUTTON_SCROLL_BACK; break; case SDLK_KP2: case SDLK_DOWN: new_btn = BUTTON_SCROLL_FWD; break; case SDLK_KP9: case SDLK_PAGEUP: new_btn = BUTTON_UP; break; case SDLK_KP3: case SDLK_PAGEDOWN: new_btn = BUTTON_DOWN; break; case SDLK_KP1: case SDLK_HOME: new_btn = BUTTON_POWER; break; case SDLK_KP7: case SDLK_END: new_btn = BUTTON_REC; break; case SDLK_KP5: case SDLK_SPACE: new_btn = BUTTON_SELECT; break; #elif CONFIG_KEYPAD == SANSA_C200_PAD case SDLK_KP4: case SDLK_LEFT: new_btn = BUTTON_LEFT; break; case SDLK_KP6: case SDLK_RIGHT: new_btn = BUTTON_RIGHT; break; case SDLK_KP8: case SDLK_UP: new_btn = BUTTON_UP; break; case SDLK_KP2: case SDLK_DOWN: new_btn = BUTTON_DOWN; break; case SDLK_KP3: new_btn = BUTTON_POWER; break; case SDLK_KP1: new_btn = BUTTON_REC; break; case SDLK_KP5: case SDLK_KP_ENTER: case SDLK_RETURN: new_btn = BUTTON_SELECT; break; case SDLK_KP7: new_btn = BUTTON_VOL_DOWN; break; case SDLK_KP9: new_btn = BUTTON_VOL_UP; break; #elif CONFIG_KEYPAD == MROBE500_PAD case SDLK_F9: new_btn = BUTTON_RC_HEART; break; case SDLK_F10: new_btn = BUTTON_RC_MODE; break; case SDLK_F11: new_btn = BUTTON_RC_VOL_DOWN; break; case SDLK_F12: new_btn = BUTTON_RC_VOL_UP; break; case SDLK_LEFT: new_btn = BUTTON_LEFT; break; case SDLK_RIGHT: new_btn = BUTTON_RIGHT; break; case SDLK_UP: new_btn = BUTTON_RC_PLAY; break; case SDLK_DOWN: new_btn = BUTTON_RC_DOWN; break; case SDLK_F8: case SDLK_ESCAPE: new_btn = BUTTON_POWER; break; #elif CONFIG_KEYPAD == MROBE100_PAD case SDLK_F9: new_btn = BUTTON_RC_HEART; break; case SDLK_F10: new_btn = BUTTON_RC_MODE; break; case SDLK_F11: new_btn = BUTTON_RC_VOL_DOWN; break; case SDLK_F12: new_btn = BUTTON_RC_VOL_UP; break; case SDLK_LEFT: new_btn = BUTTON_RC_FF; break; case SDLK_RIGHT: new_btn = BUTTON_RC_REW; break; case SDLK_UP: new_btn = BUTTON_RC_PLAY; break; case SDLK_DOWN: new_btn = BUTTON_RC_DOWN; break; case SDLK_KP1: new_btn = BUTTON_DISPLAY; break; case SDLK_KP7: new_btn = BUTTON_MENU; break; case SDLK_KP9: new_btn = BUTTON_PLAY; break; case SDLK_KP4: new_btn = BUTTON_LEFT; break; case SDLK_KP6: new_btn = BUTTON_RIGHT; break; case SDLK_KP8: new_btn = BUTTON_UP; break; case SDLK_KP2: new_btn = BUTTON_DOWN; break; case SDLK_KP5: case SDLK_SPACE: new_btn = BUTTON_SELECT; break; case SDLK_KP_MULTIPLY: case SDLK_F8: case SDLK_ESCAPE: new_btn = BUTTON_POWER; break; #elif CONFIG_KEYPAD == COWOND2_PAD case SDLK_ESCAPE: new_btn = BUTTON_POWER; break; case SDLK_KP_PLUS: new_btn = BUTTON_PLUS; break; case SDLK_KP_MINUS: new_btn = BUTTON_MINUS; break; case SDLK_KP_ENTER: new_btn = BUTTON_MENU; break; #elif CONFIG_KEYPAD == IAUDIO67_PAD case SDLK_UP: new_btn = BUTTON_RIGHT; break; case SDLK_DOWN: new_btn = BUTTON_LEFT; break; case SDLK_LEFT: new_btn = BUTTON_STOP; break; case SDLK_RETURN: case SDLK_KP_ENTER: case SDLK_RIGHT: new_btn = BUTTON_PLAY; break; case SDLK_PLUS: new_btn = BUTTON_VOLUP; break; case SDLK_MINUS: new_btn = BUTTON_VOLDOWN; break; case SDLK_SPACE: new_btn = BUTTON_MENU; break; case SDLK_BACKSPACE: new_btn = BUTTON_POWER; break; #elif CONFIG_KEYPAD == CREATIVEZVM_PAD case SDLK_KP1: new_btn = BUTTON_BACK; break; case SDLK_KP3: new_btn = BUTTON_MENU; break; case SDLK_KP7: new_btn = BUTTON_CUSTOM; break; case SDLK_KP9: new_btn = BUTTON_PLAY; break; case SDLK_KP4: case SDLK_LEFT: new_btn = BUTTON_LEFT; break; case SDLK_KP6: case SDLK_RIGHT: new_btn = BUTTON_RIGHT; break; case SDLK_KP8: case SDLK_UP: new_btn = BUTTON_UP; break; case SDLK_KP2: case SDLK_DOWN: new_btn = BUTTON_DOWN; break; case SDLK_KP5: case SDLK_SPACE: new_btn = BUTTON_SELECT; break; case SDLK_KP_MULTIPLY: case SDLK_F8: case SDLK_ESCAPE: new_btn = BUTTON_POWER; break; #elif CONFIG_KEYPAD == CREATIVEZV_PAD case SDLK_KP1: new_btn = BUTTON_PREV; break; case SDLK_KP3: new_btn = BUTTON_NEXT; break; case SDLK_KP7: new_btn = BUTTON_BACK; break; case SDLK_p: new_btn = BUTTON_PLAY; break; case SDLK_KP9: new_btn = BUTTON_MENU; break; case SDLK_KP4: case SDLK_LEFT: new_btn = BUTTON_LEFT; break; case SDLK_KP6: case SDLK_RIGHT: new_btn = BUTTON_RIGHT; break; case SDLK_KP8: case SDLK_UP: new_btn = BUTTON_UP; break; case SDLK_KP2: case SDLK_DOWN: new_btn = BUTTON_DOWN; break; case SDLK_KP5: case SDLK_SPACE: new_btn = BUTTON_SELECT; break; case SDLK_KP_MULTIPLY: case SDLK_F8: case SDLK_ESCAPE: new_btn = BUTTON_POWER; break; case SDLK_z: new_btn = BUTTON_VOL_DOWN; break; case SDLK_s: new_btn = BUTTON_VOL_UP; #elif CONFIG_KEYPAD == MEIZU_M6SL_PAD case SDLK_KP1: new_btn = BUTTON_PREV; break; case SDLK_KP3: new_btn = BUTTON_NEXT; break; case SDLK_KP_ENTER: case SDLK_RETURN: case SDLK_a: new_btn = BUTTON_PLAY; break; case SDLK_KP_PERIOD: case SDLK_INSERT: new_btn = BUTTON_MENU; break; case SDLK_KP8: case SDLK_UP: new_btn = BUTTON_UP; break; case SDLK_KP2: case SDLK_DOWN: new_btn = BUTTON_DOWN; break; case SDLK_KP5: case SDLK_SPACE: new_btn = BUTTON_SELECT; break; #elif CONFIG_KEYPAD == SANSA_FUZE_PAD case SDLK_KP4: case SDLK_LEFT: new_btn = BUTTON_LEFT; break; case SDLK_KP6: case SDLK_RIGHT: new_btn = BUTTON_RIGHT; break; case SDLK_KP8: case SDLK_UP: new_btn = BUTTON_SCROLL_BACK; break; case SDLK_KP2: case SDLK_DOWN: new_btn = BUTTON_SCROLL_FWD; break; case SDLK_PAGEUP: case SDLK_KP9: new_btn = BUTTON_UP; break; case SDLK_PAGEDOWN: case SDLK_KP3: new_btn = BUTTON_DOWN; break; case SDLK_KP_MINUS: case SDLK_KP1: new_btn = BUTTON_POWER; break; case SDLK_KP_MULTIPLY: new_btn = BUTTON_HOME; break; case SDLK_KP5: case SDLK_SPACE: case SDLK_KP_ENTER: case SDLK_RETURN: new_btn = BUTTON_SELECT; break; #elif CONFIG_KEYPAD == SANSA_CLIP_PAD case SDLK_KP4: case SDLK_LEFT: new_btn = BUTTON_LEFT; break; case SDLK_KP6: case SDLK_RIGHT: new_btn = BUTTON_RIGHT; break; case SDLK_KP8: case SDLK_UP: new_btn = BUTTON_UP; break; case SDLK_KP2: case SDLK_DOWN: new_btn = BUTTON_DOWN; break; case SDLK_INSERT: case SDLK_KP_MULTIPLY: new_btn = BUTTON_HOME; break; case SDLK_SPACE: case SDLK_KP5: new_btn = BUTTON_SELECT; break; case SDLK_PAGEDOWN: case SDLK_KP3: new_btn = BUTTON_VOL_DOWN; break; case SDLK_PAGEUP: case SDLK_KP9: new_btn = BUTTON_VOL_UP; break; case SDLK_ESCAPE: case SDLK_KP1: new_btn = BUTTON_POWER; break; #elif CONFIG_KEYPAD == SANSA_M200_PAD case SDLK_KP4: case SDLK_LEFT: new_btn = BUTTON_LEFT; break; case SDLK_KP6: case SDLK_RIGHT: new_btn = BUTTON_RIGHT; break; case SDLK_KP8: case SDLK_UP: new_btn = BUTTON_UP; break; case SDLK_KP2: case SDLK_DOWN: new_btn = BUTTON_DOWN; break; case SDLK_PLUS: new_btn = BUTTON_POWER; break; case SDLK_KP5: new_btn = BUTTON_SELECT; break; case SDLK_KP7: new_btn = BUTTON_VOL_DOWN; break; case SDLK_KP9: new_btn = BUTTON_VOL_UP; break; #elif CONFIG_KEYPAD == PHILIPS_SA9200_PAD case SDLK_KP4: case SDLK_LEFT: new_btn = BUTTON_LEFT; break; case SDLK_KP6: case SDLK_RIGHT: new_btn = BUTTON_RIGHT; break; case SDLK_KP8: case SDLK_UP: new_btn = BUTTON_UP; break; case SDLK_KP2: case SDLK_DOWN: new_btn = BUTTON_DOWN; break; case SDLK_KP5: case SDLK_SPACE: new_btn = BUTTON_PLAY; break; case SDLK_KP7: new_btn = BUTTON_PREV; break; case SDLK_KP9: new_btn = BUTTON_NEXT; break; case SDLK_KP_ENTER: case SDLK_RETURN: new_btn = BUTTON_POWER; break; case SDLK_PAGEUP: new_btn = BUTTON_VOL_UP; break; case SDLK_PAGEDOWN: new_btn = BUTTON_VOL_DOWN; break; #elif CONFIG_KEYPAD == PHILIPS_HDD1630_PAD case SDLK_KP4: case SDLK_LEFT: new_btn = BUTTON_LEFT; break; case SDLK_KP6: case SDLK_RIGHT: new_btn = BUTTON_RIGHT; break; case SDLK_KP8: case SDLK_UP: new_btn = BUTTON_UP; break; case SDLK_KP2: case SDLK_DOWN: new_btn = BUTTON_DOWN; break; case SDLK_KP5: case SDLK_SPACE: new_btn = BUTTON_SELECT; break; case SDLK_KP7: case SDLK_ESCAPE: new_btn = BUTTON_POWER; break; case SDLK_KP1: new_btn = BUTTON_PLAYLIST; break; case SDLK_KP9: new_btn = BUTTON_VOL_UP; break; case SDLK_KP3: new_btn = BUTTON_VOL_DOWN; break; case SDLK_KP_MINUS: new_btn = BUTTON_MENU; break; case SDLK_KP_PLUS: new_btn = BUTTON_VIEW; break; #elif CONFIG_KEYPAD == ONDAVX747_PAD case SDLK_ESCAPE: new_btn = BUTTON_POWER; break; case SDLK_KP_PLUS: case SDLK_RIGHT: new_btn = BUTTON_VOL_UP; break; case SDLK_KP_MINUS: case SDLK_LEFT: new_btn = BUTTON_VOL_DOWN; break; case SDLK_KP_ENTER: case SDLK_RETURN: new_btn = BUTTON_MENU; break; #elif CONFIG_KEYPAD == ONDAVX777_PAD case SDLK_ESCAPE: new_btn = BUTTON_POWER; break; #elif CONFIG_KEYPAD == SAMSUNG_YH_PAD case SDLK_KP4: case SDLK_LEFT: new_btn = BUTTON_LEFT; break; case SDLK_KP6: case SDLK_RIGHT: new_btn = BUTTON_RIGHT; break; case SDLK_KP8: case SDLK_UP: new_btn = BUTTON_UP; break; case SDLK_KP2: case SDLK_DOWN: new_btn = BUTTON_DOWN; break; case SDLK_KP5: case SDLK_KP_ENTER: new_btn = BUTTON_PLAY; break; case SDLK_KP9: case SDLK_PAGEUP: new_btn = BUTTON_FFWD; break; #ifdef SAMSUNG_YH820 case SDLK_KP7: #else case SDLK_KP3: #endif case SDLK_PAGEDOWN: new_btn = BUTTON_REW; break; case SDLK_KP_PLUS: new_btn = BUTTON_REC; break; #elif CONFIG_KEYPAD == MINI2440_PAD case SDLK_LEFT: new_btn = BUTTON_LEFT; break; case SDLK_RIGHT: new_btn = BUTTON_RIGHT; break; case SDLK_UP: new_btn = BUTTON_UP; break; case SDLK_DOWN: new_btn = BUTTON_DOWN; break; case SDLK_F8: case SDLK_ESCAPE: new_btn = BUTTON_POWER; break; case SDLK_KP_ENTER: case SDLK_RETURN: case SDLK_a: new_btn = BUTTON_A; break; case SDLK_SPACE: new_btn = BUTTON_SELECT; break; case SDLK_KP_PERIOD: case SDLK_INSERT: new_btn = BUTTON_MENU; break; case SDLK_KP_PLUS: new_btn = BUTTON_VOL_UP; break; case SDLK_KP_MINUS: new_btn = BUTTON_VOL_DOWN; break; #else #error No keymap defined! #endif /* CONFIG_KEYPAD */ case SDLK_KP0: case SDLK_F5: if(pressed) { sim_trigger_screendump(); return; } break; } /* Call to make up for scrollwheel target implementation. This is * not handled in the main button.c driver, but on the target * implementation (look at button-e200.c for example if you are trying to * figure out why using button_get_data needed a hack before). */ #if defined(BUTTON_SCROLL_FWD) && defined(BUTTON_SCROLL_BACK) if((new_btn == BUTTON_SCROLL_FWD || new_btn == BUTTON_SCROLL_BACK) && pressed) { /* Clear these buttons from the data - adding them to the queue is * handled in the scrollwheel drivers for the targets. They do not * store the scroll forward/back buttons in their button data for * the button_read call. */ queue_post(&button_queue, new_btn, 1<<24); new_btn &= ~(BUTTON_SCROLL_FWD | BUTTON_SCROLL_BACK); } #endif if (pressed) btn |= new_btn; else btn &= ~new_btn; }
void buf_set_base_handle(int handle_id) { LOGFQUEUE("buffering > Q_BASE_HANDLE %d", handle_id); queue_post(&buffering_queue, Q_BASE_HANDLE, handle_id); }
void usb_acknowledge(long id) { queue_post(&sim_queue, id, 0); }
static void usb_thread(void) { int num_acks_to_expect = 0; struct queue_event ev; while(1) { queue_wait(&usb_queue, &ev); switch(ev.id) { #ifdef USB_DRIVER_CLOSE case USB_QUIT: return; #endif #ifdef HAVE_USBSTACK case USB_TRANSFER_COMPLETION: usb_core_handle_transfer_completion( (struct usb_transfer_completion_event_data*)ev.data); break; #endif #ifdef USB_DETECT_BY_DRV /* In this case, these events the handle cable insertion USB * driver determines INSERTED/EXTRACTED state. */ case USB_POWERED: /* Set the state to USB_POWERED for now and enable the driver * to detect a bus reset only. If a bus reset is detected, * USB_INSERTED will be received. */ usb_state = USB_POWERED; usb_enable(true); break; case USB_UNPOWERED: usb_enable(false); /* This part shouldn't be obligatory for anything that can * reliably detect removal of the data lines. USB_EXTRACTED * could be posted on that event while bus power remains * available. */ queue_post(&usb_queue, USB_EXTRACTED, 0); break; #endif /* USB_DETECT_BY_DRV */ case USB_INSERTED: #ifdef HAVE_LCD_BITMAP if(do_screendump_instead_of_usb) { usb_state = USB_SCREENDUMP; screen_dump(); #ifdef HAVE_REMOTE_LCD remote_screen_dump(); #endif break; } #endif #ifdef HAVE_USB_POWER if(usb_power_button()) { /* Only charging is desired */ usb_state = USB_POWERED; #ifdef HAVE_USBSTACK #ifdef USB_ENABLE_STORAGE usb_core_enable_driver(USB_DRIVER_MASS_STORAGE, false); #endif #ifdef USB_ENABLE_HID #ifdef USB_ENABLE_CHARGING_ONLY usb_core_enable_driver(USB_DRIVER_HID, false); #else usb_core_enable_driver(USB_DRIVER_HID, true); #endif /* USB_ENABLE_CHARGING_ONLY */ #endif /* USB_ENABLE_HID */ #ifdef USB_ENABLE_CHARGING_ONLY usb_core_enable_driver(USB_DRIVER_CHARGING_ONLY, true); #endif usb_attach(); #endif break; } #endif /* HAVE_USB_POWER */ #ifdef HAVE_USBSTACK #ifdef HAVE_USB_POWER /* Set the state to USB_POWERED for now. If permission to connect * by threads and storage is granted it will be changed to * USB_CONNECTED. */ usb_state = USB_POWERED; #endif #ifdef USB_ENABLE_STORAGE usb_core_enable_driver(USB_DRIVER_MASS_STORAGE, true); #endif #ifdef USB_ENABLE_HID usb_core_enable_driver(USB_DRIVER_HID, usb_hid); #endif #ifdef USB_ENABLE_CHARGING_ONLY usb_core_enable_driver(USB_DRIVER_CHARGING_ONLY, false); #endif /* Check any drivers enabled at this point for exclusive storage * access requirements. */ exclusive_storage_access = usb_core_any_exclusive_storage(); if(!exclusive_storage_access) { usb_attach(); break; } #endif /* HAVE_USBSTACK */ /* Tell all threads that they have to back off the storage. We subtract one for our own thread. */ num_acks_to_expect = queue_broadcast(SYS_USB_CONNECTED, 0) - 1; DEBUGF("USB inserted. Waiting for ack from %d threads...\n", num_acks_to_expect); break; case SYS_USB_CONNECTED_ACK: if(num_acks_to_expect > 0 && --num_acks_to_expect == 0) { DEBUGF("All threads have acknowledged the connect.\n"); usb_slave_mode(true); usb_state = USB_INSERTED; } else { DEBUGF("usb: got ack, %d to go...\n", num_acks_to_expect); } break; case USB_EXTRACTED: #ifdef HAVE_LCD_BITMAP if(usb_state == USB_SCREENDUMP) { usb_state = USB_EXTRACTED; break; /* Connected for screendump only */ } #endif #ifndef HAVE_USBSTACK /* Stack must undo this if POWERED state was transitional */ #ifdef HAVE_USB_POWER if(usb_state == USB_POWERED) { usb_state = USB_EXTRACTED; break; } #endif #endif /* HAVE_USBSTACK */ if(usb_state == USB_INSERTED) { /* Only disable the USB mode if we really have enabled it some threads might not have acknowledged the insertion */ usb_slave_mode(false); } usb_state = USB_EXTRACTED; #ifdef HAVE_USBSTACK if(!exclusive_storage_access) { #ifndef USB_DETECT_BY_DRV /* Disabled handling USB_UNPOWERED */ usb_enable(false); #endif break; } #endif /* HAVE_USBSTACK */ num_acks_to_expect = usb_release_exclusive_storage(); break; case SYS_USB_DISCONNECTED_ACK: if(num_acks_to_expect > 0 && --num_acks_to_expect == 0) { DEBUGF("All threads have acknowledged. " "We're in business.\n"); } else { DEBUGF("usb: got ack, %d to go...\n", num_acks_to_expect); } break; #ifdef HAVE_HOTSWAP case SYS_HOTSWAP_INSERTED: case SYS_HOTSWAP_EXTRACTED: #ifdef HAVE_USBSTACK usb_core_hotswap_event(1,ev.id == SYS_HOTSWAP_INSERTED); #else /* !HAVE_USBSTACK */ if(usb_state == USB_INSERTED) { #if (CONFIG_STORAGE & STORAGE_MMC) usb_enable(false); usb_mmc_countdown = HZ/2; /* re-enable after 0.5 sec */ #endif /* STORAGE_MMC */ } #endif /* HAVE_USBSTACK */ break; #if (CONFIG_STORAGE & STORAGE_MMC) case USB_REENABLE: if(usb_state == USB_INSERTED) usb_enable(true); /* reenable only if still inserted */ break; #endif /* STORAGE_MMC */ #endif /* HAVE_HOTSWAP */ #ifdef USB_FIREWIRE_HANDLING case USB_REQUEST_REBOOT: #ifdef HAVE_USB_POWER if (usb_reboot_button()) #endif try_reboot(); break; #endif /* USB_FIREWIRE_HANDLING */ #if defined(HAVE_USB_CHARGING_ENABLE) && defined(HAVE_USBSTACK) case USB_CHARGER_UPDATE: usb_charging_maxcurrent_change(usb_charging_maxcurrent()); break; #endif } } }
void sim_trigger_screendump(void) { queue_post(&sim_queue, SIM_SCREENDUMP, 0); }
static void handle_scroll_wheel(int new_scroll) { static const signed char scroll_state[4][4] = { {0, 1, -1, 0}, {-1, 0, 0, 1}, {1, 0, 0, -1}, {0, -1, 1, 0} }; static int prev_scroll = -1; static int direction = 0; static int count = 0; static long next_backlight_on = 0; int wheel_keycode = BUTTON_NONE; int scroll; static unsigned long wheel_delta = 1ul << 24; static unsigned long wheel_velocity = 0; static unsigned long last_wheel_usec = 0; static int prev_keypost = BUTTON_NONE; unsigned long usec; unsigned long v; if ( prev_scroll == -1 ) { prev_scroll = new_scroll; return; } scroll = scroll_state[prev_scroll][new_scroll]; prev_scroll = new_scroll; if (direction != scroll) { /* direction reversal or was hold - reset all */ direction = scroll; count = 0; prev_keypost = BUTTON_NONE; wheel_velocity = 0; wheel_delta = 1ul << 24; return; } /* poke backlight every 1/4s of activity */ if (TIME_AFTER(current_tick, next_backlight_on)) { backlight_on(); reset_poweroff_timer(); next_backlight_on = current_tick + HZ/4; } if (++count < WHEEL_BASE_SENSITIVITY) return; count = 0; /* Mini 1st Gen wheel has inverse direction mapping * compared to 1st..3rd Gen wheel. */ switch (direction) { case 1: wheel_keycode = BUTTON_SCROLL_FWD; break; case -1: wheel_keycode = BUTTON_SCROLL_BACK; break; default: /* only happens if we get out of sync */ break; } /* have a keycode */ usec = USEC_TIMER; v = usec - last_wheel_usec; /* calculate deg/s based upon sensitivity-adjusted interrupt period */ if ((long)v <= 0) { /* timer wrapped (no activity for awhile), skip acceleration */ v = 0; wheel_delta = 1ul << 24; } else { if (v > 0xfffffffful/WHEELCLICKS_PER_ROTATION) { v = 0xfffffffful/WHEELCLICKS_PER_ROTATION; /* check overflow below */ } v = 360000000ul*WHEEL_BASE_SENSITIVITY / (v*WHEELCLICKS_PER_ROTATION); if (v > 0xfffffful) v = 0xfffffful; /* limit to 24 bits */ } if (v < WHEEL_SMOOTHING_VELOCITY) { /* very slow - no smoothing */ wheel_velocity = v; /* ensure backlight never gets stuck for an extended period if tick * wrapped such that next poke is very far ahead */ next_backlight_on = current_tick - 1; } else { /* some velocity filtering to smooth things out */ wheel_velocity = (7*wheel_velocity + v) / 8; } if (queue_empty(&button_queue)) { int key = wheel_keycode; if (v >= WHEEL_REPEAT_VELOCITY && prev_keypost == key) { /* quick enough and same key is being posted more than once in a * row - generate repeats - use unsmoothed v to guage */ key |= BUTTON_REPEAT; } prev_keypost = wheel_keycode; /* post wheel keycode with wheel data */ queue_post(&button_queue, key, (wheel_velocity >= WHEEL_ACCEL_START ? (1ul << 31) : 0) | wheel_delta | wheel_velocity); /* message posted - reset delta */ wheel_delta = 1ul << 24; } else { /* skipped post - increment delta and limit to 7 bits */ wheel_delta += 1ul << 24; if (wheel_delta > (0x7ful << 24)) wheel_delta = 0x7ful << 24; } last_wheel_usec = usec; }
void usb_signal_transfer_completion( struct usb_transfer_completion_event_data* event_data) { queue_post(&usb_queue, USB_TRANSFER_COMPLETION, (intptr_t)event_data); }