Ejemplo n.º 1
0
    /* 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
}
Ejemplo n.º 2
0
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;
}
Ejemplo n.º 3
0
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);
    }
}
Ejemplo n.º 4
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;
}
Ejemplo n.º 5
0
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;
    }
}
Ejemplo n.º 6
0
/* 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;
}
Ejemplo n.º 7
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);
}
Ejemplo n.º 8
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);
}
Ejemplo n.º 9
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++;
	}
}
Ejemplo n.º 10
0
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);
}
Ejemplo n.º 11
0
/* 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();
}
Ejemplo n.º 12
0
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);
    }
}
Ejemplo n.º 13
0
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 */
}
Ejemplo n.º 14
0
void buttonlight_off(void)
{
    queue_post(&backlight_queue, BUTTON_LIGHT_OFF, 0);
}
Ejemplo n.º 15
0
/* external interface */
void buttonlight_on(void)
{
    queue_remove_from_head(&backlight_queue, BUTTON_LIGHT_ON);
    queue_post(&backlight_queue, BUTTON_LIGHT_ON, 0);
}
Ejemplo n.º 16
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;
}
Ejemplo n.º 17
0
static void pmu_eint_isr(struct eint_handler *h)
{
     eint_unregister(h);
     queue_post(&pmu_queue, Q_EINT, 0);
}
Ejemplo n.º 18
0
void usb_charger_update(void)
{
    queue_post(&usb_queue, USB_CHARGER_UPDATE, 0);
}
Ejemplo n.º 19
0
void audio_queue_post(long id, intptr_t data)
{
    queue_post(&audio_queue, id, data);
}
Ejemplo n.º 20
0
void usb_firewire_connect_event(void)
{
    queue_post(&usb_queue, USB_REQUEST_REBOOT, 0);
}
Ejemplo n.º 21
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 */
    }
}
Ejemplo n.º 22
0
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;
}
Ejemplo n.º 23
0
void buttonlight_set_timeout(int value)
{
    buttonlight_timeout = HZ * value;
    queue_post(&backlight_queue, BUTTON_LIGHT_TMO_CHANGED, 0);
}
Ejemplo n.º 24
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;
}
Ejemplo n.º 25
0
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);
}
Ejemplo n.º 26
0
void usb_acknowledge(long id)
{
    queue_post(&sim_queue, id, 0);
}
Ejemplo n.º 27
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
        }
    }
}
Ejemplo n.º 28
0
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;
}
Ejemplo n.º 30
0
void usb_signal_transfer_completion(
    struct usb_transfer_completion_event_data* event_data)
{
    queue_post(&usb_queue, USB_TRANSFER_COMPLETION, (intptr_t)event_data);
}