/* Copyright (C) 2007-2008 The Android Open Source Project
**
** This software is licensed under the terms of the GNU General Public
** License version 2, as published by the Free Software Foundation, and
** may be copied, distributed, and modified under those terms.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
** GNU General Public License for more details.
*/
#include "android/skin/window.h"
#include "android/skin/image.h"
#include "android/skin/scaler.h"
#include "android/charmap.h"
#include "android/utils/debug.h"
#include "android/utils/system.h"
#include "android/utils/duff.h"
#include "android/protocol/core-commands-api.h"
#include <SDL_syswm.h>
#include "user-events.h"
#include <math.h>

#include "android/framebuffer.h"
#include "android/opengles.h"

/* when shrinking, we reduce the pixel ratio by this fixed amount */
#define  SHRINK_SCALE  0.6

/* maximum value of LCD brighness */
#define  LCD_BRIGHTNESS_MIN      0
#define  LCD_BRIGHTNESS_DEFAULT  128
#define  LCD_BRIGHTNESS_MAX      255

typedef struct Background {
    SkinImage*   image;
    SkinRect     rect;
    SkinPos      origin;
} Background;

static void
background_done( Background*  back )
{
    skin_image_unref( &back->image );
}

static void
background_init( Background*  back, SkinBackground*  sback, SkinLocation*  loc, SkinRect*  frame )
{
    SkinRect  r;

    back->image = skin_image_rotate( sback->image, loc->rotation );
    skin_rect_rotate( &r, &sback->rect, loc->rotation );
    r.pos.x += loc->anchor.x;
    r.pos.y += loc->anchor.y;

    back->origin = r.pos;
    skin_rect_intersect( &back->rect, &r, frame );
}

static void
background_redraw( Background*  back, SkinRect*  rect, SDL_Surface*  surface )
{
    SkinRect  r;

    if (skin_rect_intersect( &r, rect, &back->rect ) )
    {
        SDL_Rect  rd, rs;

        rd.x = r.pos.x;
        rd.y = r.pos.y;
        rd.w = r.size.w;
        rd.h = r.size.h;

        rs.x = r.pos.x - back->origin.x;
        rs.y = r.pos.y - back->origin.y;
        rs.w = r.size.w;
        rs.h = r.size.h;

        SDL_BlitSurface( skin_image_surface(back->image), &rs, surface, &rd );
        //SDL_UpdateRects( surface, 1, &rd );
    }
}


typedef struct ADisplay {
    SkinRect       rect;
    SkinPos        origin;
    SkinRotation   rotation;
    SkinSize       datasize;  /* framebuffer size */
    void*          data;      /* framebuffer pixels */
    QFrameBuffer*  qfbuff;
    SkinImage*     onion;       /* onion image */
    SkinRect       onion_rect;  /* onion rect, if any */
    int            brightness;
} ADisplay;

static void
display_done( ADisplay*  disp )
{
    disp->data   = NULL;
    disp->qfbuff = NULL;
    skin_image_unref( &disp->onion );
}

static int
display_init( ADisplay*  disp, SkinDisplay*  sdisp, SkinLocation*  loc, SkinRect*  frame )
{
    skin_rect_rotate( &disp->rect, &sdisp->rect, loc->rotation );
    disp->rect.pos.x += loc->anchor.x;
    disp->rect.pos.y += loc->anchor.y;

    disp->rotation = (loc->rotation + sdisp->rotation) & 3;
    switch (disp->rotation) {
        case SKIN_ROTATION_0:
            disp->origin = disp->rect.pos;
            break;

        case SKIN_ROTATION_90:
            disp->origin.x = disp->rect.pos.x + disp->rect.size.w;
            disp->origin.y = disp->rect.pos.y;
            break;

        case SKIN_ROTATION_180:
            disp->origin.x = disp->rect.pos.x + disp->rect.size.w;
            disp->origin.y = disp->rect.pos.y + disp->rect.size.h;
            break;

        default:
            disp->origin.x = disp->rect.pos.x;
            disp->origin.y = disp->rect.pos.y + disp->rect.size.h;
            break;
    }
    skin_size_rotate( &disp->datasize, &sdisp->rect.size, sdisp->rotation );
    skin_rect_intersect( &disp->rect, &disp->rect, frame );
#if 0
    fprintf(stderr, "... display_init  rect.pos(%d,%d) rect.size(%d,%d) datasize(%d,%d)\n",
                    disp->rect.pos.x, disp->rect.pos.y,
                    disp->rect.size.w, disp->rect.size.h,
                    disp->datasize.w, disp->datasize.h);
#endif
    disp->qfbuff = sdisp->qfbuff;
    disp->data   = sdisp->qfbuff->pixels;
    disp->onion  = NULL;

    disp->brightness = LCD_BRIGHTNESS_DEFAULT;

    return (disp->data == NULL) ? -1 : 0;
}

static __inline__ uint32_t rgb565_to_rgba32(uint32_t pix,
        uint32_t rshift, uint32_t gshift, uint32_t bshift, uint32_t amask)
{
    uint32_t r8 = ((pix & 0xf800) >>  8) | ((pix & 0xe000) >> 13);
    uint32_t g8 = ((pix & 0x07e0) >>  3) | ((pix & 0x0600) >>  9);
    uint32_t b8 = ((pix & 0x001f) <<  3) | ((pix & 0x001c) >>  2);
    return (r8 << rshift) | (g8 << gshift) | (b8 << bshift) | amask;
}

/* The framebuffer format is R,G,B,X in framebuffer memory, on a
 * little-endian system, this translates to XBGR after a load.
 */
static __inline__ uint32_t xbgr_to_rgba32(uint32_t pix,
        uint32_t rshift, uint32_t gshift, uint32_t bshift, uint32_t amask)
{
    uint32_t r8 = (pix & 0x00ff0000) >> 16;
    uint32_t g8 = (pix & 0x0000ff00) >>  8;
    uint32_t b8 = (pix & 0x000000ff) >>  0;
    return (r8 << rshift) | (g8 << gshift) | (b8 << bshift) | amask;
}

static void
display_set_onion( ADisplay*  disp, SkinImage*  onion, SkinRotation  rotation, int  blend )
{
    int        onion_w, onion_h;
    SkinRect*  rect  = &disp->rect;
    SkinRect*  orect = &disp->onion_rect;

    rotation = (rotation + disp->rotation) & 3;

    skin_image_unref( &disp->onion );
    disp->onion = skin_image_clone_full( onion, rotation, blend );

    onion_w = skin_image_w(disp->onion);
    onion_h = skin_image_h(disp->onion);

    switch (rotation) {
        case SKIN_ROTATION_0:
            orect->pos = rect->pos;
            break;

        case SKIN_ROTATION_90:
            orect->pos.x = rect->pos.x + rect->size.w - onion_w;
            orect->pos.y = rect->pos.y;
            break;

        case SKIN_ROTATION_180:
            orect->pos.x = rect->pos.x + rect->size.w - onion_w;
            orect->pos.y = rect->pos.y + rect->size.h - onion_h;
            break;

        default:
            orect->pos.x = rect->pos.x;
            orect->pos.y = rect->pos.y + rect->size.h - onion_h;
    }
    orect->size.w = onion_w;
    orect->size.h = onion_h;
}

#define  DOT_MATRIX  0

#if DOT_MATRIX

static void
dotmatrix_dither_argb32( unsigned char*  pixels, int  x, int  y, int  w, int  h, int  pitch )
{
    static const unsigned dotmatrix_argb32[16] = {
        0x003f00, 0x00003f, 0x3f0000, 0x000000,
        0x3f3f3f, 0x000000, 0x3f3f3f, 0x000000,
        0x3f0000, 0x000000, 0x003f00, 0x00003f,
        0x3f3f3f, 0x000000, 0x3f3f3f, 0x000000
    };

    int   yy = y & 3;

    pixels += 4*x + y*pitch;

    for ( ; h > 0; h-- ) {
        unsigned*  line = (unsigned*) pixels;
        int        nn, xx = x & 3;

        for (nn = 0; nn < w; nn++) {
            unsigned  c = line[nn];

            c = c - ((c >> 2) & dotmatrix_argb32[(yy << 2)|xx]);

            xx = (xx + 1) & 3;
            line[nn] = c;
        }

        yy      = (yy + 1) & 3;
        pixels += pitch;
    }
}

#endif /* DOT_MATRIX */

/* technical note about the lightness emulation
 *
 * we try to emulate something that looks like the Dream's
 * non-linear LCD lightness, without going too dark or bright.
 *
 * the default lightness is around 105 (about 40%) and we prefer
 * to keep full RGB colors at that setting, to not alleviate
 * developers who will not understand why the emulator's colors
 * look slightly too dark.
 *
 * we also want to implement a 'bright' mode by de-saturating
 * colors towards bright white.
 *
 * All of this leads to the implementation below that looks like
 * the following:
 *
 * if (level == MIN)
 *     screen is off
 *
 * if (level > MIN && level < LOW)
 *     interpolate towards black, with
 *     MINALPHA = 0.2
 *     alpha = MINALPHA + (1-MINALPHA)*(level-MIN)/(LOW-MIN)
 *
 * if (level >= LOW && level <= HIGH)
 *     keep full RGB colors
 *
 * if (level > HIGH)
 *     interpolate towards bright white, with
 *     MAXALPHA = 0.6
 *     alpha = MAXALPHA*(level-HIGH)/(MAX-HIGH)
 *
 * we probably want some sort of power law instead of interpolating
 * linearly, but frankly, this is sufficient for most uses.
 */

#define  LCD_BRIGHTNESS_LOW   80
#define  LCD_BRIGHTNESS_HIGH  180

#define  LCD_ALPHA_LOW_MIN      0.2
#define  LCD_ALPHA_HIGH_MAX     0.6

/* treat as special value to turn screen off */
#define  LCD_BRIGHTNESS_OFF   LCD_BRIGHTNESS_MIN

static void
lcd_brightness_argb32( unsigned char*  pixels, SkinRect*  r, int  pitch, int  brightness )
{
    const unsigned  b_min  = LCD_BRIGHTNESS_MIN;
    const unsigned  b_max  = LCD_BRIGHTNESS_MAX;
    const unsigned  b_low  = LCD_BRIGHTNESS_LOW;
    const unsigned  b_high = LCD_BRIGHTNESS_HIGH;

    unsigned        alpha = brightness;
    int             w     = r->size.w;
    int             h     = r->size.h;

    if (alpha <= b_min)
        alpha = b_min;
    else if (alpha > b_max)
        alpha = b_max;

    pixels += 4*r->pos.x + r->pos.y*pitch;

    if (alpha < b_low)
    {
        const unsigned  alpha_min   = (255*LCD_ALPHA_LOW_MIN);
        const unsigned  alpha_range = (255 - alpha_min);

        alpha = alpha_min + ((alpha - b_min)*alpha_range) / (b_low - b_min);

        for ( ; h > 0; h-- ) {
            unsigned*  line = (unsigned*) pixels;
            int        nn   = 0;

            DUFF4(w, {
                unsigned  c  = line[nn];
                unsigned  ag = (c >> 8) & 0x00ff00ff;
                unsigned  rb = (c)      & 0x00ff00ff;

                ag = (ag*alpha)        & 0xff00ff00;
                rb = ((rb*alpha) >> 8) & 0x00ff00ff;

                line[nn] = (unsigned)(ag | rb);
                nn++;
            });
            pixels += pitch;
        }
    }
    else if (alpha > LCD_BRIGHTNESS_HIGH) /* 'superluminous' mode */
    {
        const unsigned  alpha_max   = (255*LCD_ALPHA_HIGH_MAX);
        const unsigned  alpha_range = (255-alpha_max);
        unsigned        ialpha;

        alpha  = ((alpha - b_high)*alpha_range) / (b_max - b_high);
        ialpha = 255-alpha;

        for ( ; h > 0; h-- ) {
            unsigned*  line = (unsigned*) pixels;
            int        nn   = 0;

            DUFF4(w, {
                unsigned  c  = line[nn];
                unsigned  ag = (c >> 8) & 0x00ff00ff;
                unsigned  rb = (c)      & 0x00ff00ff;

                /* interpolate towards bright white, i.e. 0x00ffffff */
                ag = ((ag*ialpha + 0x00ff00ff*alpha)) & 0xff00ff00;
                rb = ((rb*ialpha + 0x00ff00ff*alpha) >> 8) & 0x00ff00ff;

                line[nn] = (unsigned)(ag | rb);
                nn++;
            });
            pixels += pitch;
        }
    }
}


/* this is called when the LCD framebuffer is off */
static void
lcd_off_argb32( unsigned char*  pixels, SkinRect*  r, int  pitch )
{
    int  x = r->pos.x;
    int  y = r->pos.y;
    int  w = r->size.w;
    int  h = r->size.h;

    pixels += 4*x + y*pitch;
    for ( ; h > 0; h-- ) {
        memset( pixels, 0, w*4 );
        pixels += pitch;
    }
}

static void
display_redraw_rect16( ADisplay* disp, SkinRect* rect, SDL_Surface* surface)
{
    int           x  = rect->pos.x - disp->rect.pos.x;
    int           y  = rect->pos.y - disp->rect.pos.y;
    int           w  = rect->size.w;
    int           h  = rect->size.h;
    int           disp_w    = disp->rect.size.w;
    int           disp_h    = disp->rect.size.h;
    int           dst_pitch = surface->pitch;
    uint8_t*      dst_line  = (uint8_t*)surface->pixels + rect->pos.x*4 + rect->pos.y*dst_pitch;
    int           src_pitch = disp->datasize.w*2;
    uint8_t*      src_line  = (uint8_t*)disp->data;
    int           yy, xx;
    uint32_t      rshift = surface->format->Rshift;
    uint32_t      gshift = surface->format->Gshift;
    uint32_t      bshift = surface->format->Bshift;
    uint32_t      amask  = surface->format->Amask; // may be 0x00 for non-alpha format

    switch ( disp->rotation & 3 )
    {
    case ANDROID_ROTATION_0:
        src_line += x*2 + y*src_pitch;

        for (yy = h; yy > 0; yy--)
        {
            uint32_t*  dst = (uint32_t*)dst_line;
            uint16_t*  src = (uint16_t*)src_line;

            xx = 0;
            DUFF4(w, {
                dst[xx] = rgb565_to_rgba32(src[xx], rshift, gshift, bshift, amask);
                xx++;
            });
            src_line += src_pitch;
            dst_line += dst_pitch;
        }
        break;

    case ANDROID_ROTATION_90:
        src_line += y*2 + (disp_w - x - 1)*src_pitch;

        for (yy = h; yy > 0; yy--)
        {
            uint32_t*  dst = (uint32_t*)dst_line;
            uint8_t*   src = src_line;

            DUFF4(w, {
                dst[0] = rgb565_to_rgba32(((uint16_t*)src)[0], rshift, gshift, bshift, amask);
                src -= src_pitch;
                dst += 1;
            });
            src_line += 2;
            dst_line += dst_pitch;
        }
        break;

    case ANDROID_ROTATION_180:
        src_line += (disp_w -1 - x)*2 + (disp_h-1-y)*src_pitch;

        for (yy = h; yy > 0; yy--)
        {
            uint16_t*  src = (uint16_t*)src_line;
            uint32_t*  dst = (uint32_t*)dst_line;

            DUFF4(w, {
                dst[0] = rgb565_to_rgba32(src[0], rshift, gshift, bshift, amask);
                src -= 1;
                dst += 1;
            });
            src_line -= src_pitch;
            dst_line += dst_pitch;
    }
    break;

    default:  /* ANDROID_ROTATION_270 */
        src_line += (disp_h-1-y)*2 + x*src_pitch;

        for (yy = h; yy > 0; yy--)
        {
            uint32_t*  dst = (uint32_t*)dst_line;
            uint8_t*   src = src_line;

            DUFF4(w, {
                dst[0] = rgb565_to_rgba32(((uint16_t*)src)[0], rshift, gshift, bshift, amask);
                dst   += 1;
                src   += src_pitch;
            });
            src_line -= 2;
            dst_line += dst_pitch;
        }
    }
}

static void
display_redraw_rect32( ADisplay* disp, SkinRect* rect,SDL_Surface* surface)
{
    int           x  = rect->pos.x - disp->rect.pos.x;
    int           y  = rect->pos.y - disp->rect.pos.y;
    int           w  = rect->size.w;
    int           h  = rect->size.h;
    int           disp_w    = disp->rect.size.w;
    int           disp_h    = disp->rect.size.h;
    int           dst_pitch = surface->pitch;
    uint8_t*      dst_line  = (uint8_t*)surface->pixels + rect->pos.x*4 + rect->pos.y*dst_pitch;
    int           src_pitch = disp->datasize.w*4;
    uint8_t*      src_line  = (uint8_t*)disp->data;
    int           yy;
    uint32_t      rshift = surface->format->Rshift;
    uint32_t      gshift = surface->format->Gshift;
    uint32_t      bshift = surface->format->Bshift;
    uint32_t      amask  = surface->format->Amask; // may be 0x00 for non-alpha format

    switch ( disp->rotation & 3 )
    {
    case ANDROID_ROTATION_0:
        src_line += x*4 + y*src_pitch;

        for (yy = h; yy > 0; yy--) {
            uint32_t*  src = (uint32_t*)src_line;
            uint32_t*  dst = (uint32_t*)dst_line;

            DUFF4(w, {
                dst[0] = xbgr_to_rgba32(src[0], rshift, gshift, bshift, amask);
                dst++;
                src++;
            });
            src_line += src_pitch;
            dst_line += dst_pitch;
        }
        break;

    case ANDROID_ROTATION_90:
        src_line += y*4 + (disp_w - x - 1)*src_pitch;

        for (yy = h; yy > 0; yy--)
        {
            uint32_t*  dst = (uint32_t*)dst_line;
            uint8_t*   src = src_line;

            DUFF4(w, {
                dst[0] = xbgr_to_rgba32(*(uint32_t*)src, rshift, gshift, bshift, amask);
                src -= src_pitch;
                dst += 1;
            });
            src_line += 4;
            dst_line += dst_pitch;
        }
        break;

    case ANDROID_ROTATION_180:
        src_line += (disp_w -1 - x)*4 + (disp_h-1-y)*src_pitch;

        for (yy = h; yy > 0; yy--)
        {
            uint32_t*  src = (uint32_t*)src_line;
            uint32_t*  dst = (uint32_t*)dst_line;

            DUFF4(w, {
                dst[0] = xbgr_to_rgba32(src[0], rshift, gshift, bshift, amask);
                src -= 1;
                dst += 1;
            });
            src_line -= src_pitch;
            dst_line += dst_pitch;
    }
    break;

    default:  /* ANDROID_ROTATION_270 */
        src_line += (disp_h-1-y)*4 + x*src_pitch;

        for (yy = h; yy > 0; yy--)
        {
            uint32_t*  dst = (uint32_t*)dst_line;
            uint8_t*   src = src_line;

            DUFF4(w, {
                dst[0] = xbgr_to_rgba32(*(uint32_t*)src, rshift, gshift, bshift, amask);
                dst   += 1;
                src   += src_pitch;
            });
            src_line -= 4;
            dst_line += dst_pitch;
        }
    }
}

static void
display_redraw( ADisplay*  disp, SkinRect*  rect, SDL_Surface*  surface )
{
    SkinRect  r;

    if (skin_rect_intersect( &r, rect, &disp->rect ))
    {
#if 0
        fprintf(stderr, "--- display redraw r.pos(%d,%d) r.size(%d,%d) "
                        "disp.pos(%d,%d) disp.size(%d,%d) datasize(%d,%d) rect.pos(%d,%d) rect.size(%d,%d)\n",
                        r.pos.x - disp->rect.pos.x, r.pos.y - disp->rect.pos.y,
                        r.size.w, r.size.h, disp->rect.pos.x, disp->rect.pos.y,
                        disp->rect.size.w, disp->rect.size.h, disp->datasize.w, disp->datasize.h,
                        rect->pos.x, rect->pos.y, rect->size.w, rect->size.h );
#endif
        SDL_LockSurface( surface );

        if (disp->brightness == LCD_BRIGHTNESS_OFF)
        {
            lcd_off_argb32( surface->pixels, &r, surface->pitch );
        }
        else
        {
            if (disp->qfbuff->bits_per_pixel == 32)
                display_redraw_rect32(disp, &r, surface);
            else
                display_redraw_rect16(disp, &r, surface);
#if DOT_MATRIX
            dotmatrix_dither_argb32( surface->pixels, r.pos.x, r.pos.y, r.size.w, r.size.h, surface->pitch );
#endif
            /* apply lightness */
            lcd_brightness_argb32( surface->pixels, &r, surface->pitch, disp->brightness );
        }
        SDL_UnlockSurface( surface );

        /* Apply onion skin */
        if (disp->onion != NULL) {
            SkinRect  r2;

            if ( skin_rect_intersect( &r2, &r, &disp->onion_rect ) ) {
                SDL_Rect  rs, rd;

                rd.x = r2.pos.x;
                rd.y = r2.pos.y;
                rd.w = r2.size.w;
                rd.h = r2.size.h;

                rs.x = rd.x - disp->onion_rect.pos.x;
                rs.y = rd.y - disp->onion_rect.pos.y;
                rs.w = rd.w;
                rs.h = rd.h;

                SDL_BlitSurface( skin_image_surface(disp->onion), &rs, surface, &rd );
            }
        }

        SDL_UpdateRect( surface, r.pos.x, r.pos.y, r.size.w, r.size.h );
    }
}


typedef struct Button {
    SkinImage*       image;
    SkinRect         rect;
    SkinPos          origin;
    Background*      background;
    unsigned         keycode;
    int              down;
} Button;

static void
button_done( Button*  button )
{
    skin_image_unref( &button->image );
    button->background = NULL;
}

static void
button_init( Button*  button, SkinButton*  sbutton, SkinLocation*  loc, Background*  back, SkinRect*  frame, SkinLayout*  slayout )
{
    SkinRect  r;

    button->image      = skin_image_rotate( sbutton->image, loc->rotation );
    button->background = back;
    button->keycode    = sbutton->keycode;
    button->down       = 0;

    if (slayout->has_dpad_rotation) {
        /* Dpad keys must be rotated if the skin provides a 'dpad-rotation' field.
         * this is used as a counter-measure to the fact that the framework always assumes
         * that the physical D-Pad has been rotated when in landscape mode.
         */
        button->keycode = android_keycode_rotate( button->keycode, -slayout->dpad_rotation );
    }

    skin_rect_rotate( &r, &sbutton->rect, loc->rotation );
    r.pos.x += loc->anchor.x;
    r.pos.y += loc->anchor.y;
    button->origin = r.pos;
    skin_rect_intersect( &button->rect, &r, frame );
}

static void
button_redraw( Button*  button, SkinRect*  rect, SDL_Surface*  surface )
{
    SkinRect  r;

    if (skin_rect_intersect( &r, rect, &button->rect ))
    {
        if ( button->down && button->image != SKIN_IMAGE_NONE )
        {
            SDL_Rect  rs, rd;

            rs.x = r.pos.x - button->origin.x;
            rs.y = r.pos.y - button->origin.y;
            rs.w = r.size.w;
            rs.h = r.size.h;

            rd.x = r.pos.x;
            rd.y = r.pos.y;
            rd.w = r.size.w;
            rd.h = r.size.h;

            if (button->image != SKIN_IMAGE_NONE) {
                SDL_BlitSurface( skin_image_surface(button->image), &rs, surface, &rd );
                if (button->down > 1)
                    SDL_BlitSurface( skin_image_surface(button->image), &rs, surface, &rd );
            }
        }
    }
}


typedef struct {
    char      tracking;
    char      inside;
    SkinPos   pos;
    ADisplay*  display;
} FingerState;

static void
finger_state_reset( FingerState*  finger )
{
    finger->tracking = 0;
    finger->inside   = 0;
}

typedef struct {
    Button*   pressed;
    Button*   hover;
} ButtonState;

static void
button_state_reset( ButtonState*  button )
{
    button->pressed = NULL;
    button->hover   = NULL;
}

typedef struct {
    char            tracking;
    SkinTrackBall*  ball;
    SkinRect        rect;
    SkinWindow*     window;
} BallState;

static void
ball_state_reset( BallState*  state, SkinWindow*  window )
{
    state->tracking = 0;
    state->ball     = NULL;

    state->rect.pos.x  = 0;
    state->rect.pos.y  = 0;
    state->rect.size.w = 0;
    state->rect.size.h = 0;
    state->window      = window;
}

static void
ball_state_redraw( BallState*  state, SkinRect*  rect, SDL_Surface*  surface )
{
    SkinRect  r;

    if (skin_rect_intersect( &r, rect, &state->rect ))
        skin_trackball_draw( state->ball, 0, 0, surface );
}

static void
ball_state_show( BallState*  state, int  enable )
{
    if (enable) {
        if ( !state->tracking ) {
            state->tracking = 1;
            SDL_ShowCursor(0);
            SDL_WM_GrabInput( SDL_GRAB_ON );
            skin_trackball_refresh( state->ball );
            skin_window_redraw( state->window, &state->rect );
        }
    } else {
        if ( state->tracking ) {
            state->tracking = 0;
            SDL_WM_GrabInput( SDL_GRAB_OFF );
            SDL_ShowCursor(1);
            skin_window_redraw( state->window, &state->rect );
        }
    }
}


static void
ball_state_set( BallState*  state, SkinTrackBall*  ball )
{
    ball_state_show( state, 0 );

    state->ball = ball;
    if (ball != NULL) {
        SDL_Rect  sr;

        skin_trackball_rect( ball, &sr );
        state->rect.pos.x  = sr.x;
        state->rect.pos.y  = sr.y;
        state->rect.size.w = sr.w;
        state->rect.size.h = sr.h;
    }
}

typedef struct Layout {
    int          num_buttons;
    int          num_backgrounds;
    int          num_displays;
    unsigned     color;
    Button*      buttons;
    Background*  backgrounds;
    ADisplay*    displays;
    SkinRect     rect;
    SkinLayout*  slayout;
} Layout;

#define  LAYOUT_LOOP_BUTTONS(layout,button)                          \
    do {                                                             \
        Button*  __button = (layout)->buttons;                       \
        Button*  __button_end = __button + (layout)->num_buttons;    \
        for ( ; __button < __button_end; __button ++ ) {             \
            Button*  button = __button;

#define  LAYOUT_LOOP_END_BUTTONS \
        }                        \
    } while (0);

#define  LAYOUT_LOOP_DISPLAYS(layout,display)                          \
    do {                                                               \
        ADisplay*  __display = (layout)->displays;                     \
        ADisplay*  __display_end = __display + (layout)->num_displays; \
        for ( ; __display < __display_end; __display ++ ) {            \
            ADisplay*  display = __display;

#define  LAYOUT_LOOP_END_DISPLAYS \
        }                         \
    } while (0);


static void
layout_done( Layout*  layout )
{
    int  nn;

    for (nn = 0; nn < layout->num_buttons; nn++)
        button_done( &layout->buttons[nn] );

    for (nn = 0; nn < layout->num_backgrounds; nn++)
        background_done( &layout->backgrounds[nn] );

    for (nn = 0; nn < layout->num_displays; nn++)
        display_done( &layout->displays[nn] );

    AFREE( layout->buttons );
    layout->buttons = NULL;

    AFREE( layout->backgrounds );
    layout->backgrounds = NULL;

    AFREE( layout->displays );
    layout->displays = NULL;

    layout->num_buttons     = 0;
    layout->num_backgrounds = 0;
    layout->num_displays    = 0;
}

static int
layout_init( Layout*  layout, SkinLayout*  slayout )
{
    int       n_buttons, n_backgrounds, n_displays;

    /* first, count the number of elements of each kind */
    n_buttons     = 0;
    n_backgrounds = 0;
    n_displays    = 0;

    layout->color   = slayout->color;
    layout->slayout = slayout;

    SKIN_LAYOUT_LOOP_LOCS(slayout,loc)
        SkinPart*    part = loc->part;

        if ( part->background->valid )
            n_backgrounds += 1;
        if ( part->display->valid )
            n_displays += 1;

        SKIN_PART_LOOP_BUTTONS(part, sbutton)
            n_buttons += 1;
            sbutton=sbutton;
        SKIN_PART_LOOP_END
    SKIN_LAYOUT_LOOP_END

    layout->num_buttons     = n_buttons;
    layout->num_backgrounds = n_backgrounds;
    layout->num_displays    = n_displays;

    /* now allocate arrays, then populate them */
    AARRAY_NEW0(layout->buttons,     n_buttons);
    AARRAY_NEW0(layout->backgrounds, n_backgrounds);
    AARRAY_NEW0(layout->displays,    n_displays);

    if (layout->buttons == NULL && n_buttons > 0) goto Fail;
    if (layout->backgrounds == NULL && n_backgrounds > 0) goto Fail;
    if (layout->displays == NULL && n_displays > 0) goto Fail;

    n_buttons     = 0;
    n_backgrounds = 0;
    n_displays    = 0;

    layout->rect.pos.x = 0;
    layout->rect.pos.y = 0;
    layout->rect.size  = slayout->size;

    SKIN_LAYOUT_LOOP_LOCS(slayout,loc)
        SkinPart*    part = loc->part;
        Background*  back = NULL;

        if ( part->background->valid ) {
            back = layout->backgrounds + n_backgrounds;
            background_init( back, part->background, loc, &layout->rect );
            n_backgrounds += 1;
        }
        if ( part->display->valid ) {
            ADisplay*  disp = layout->displays + n_displays;
            display_init( disp, part->display, loc, &layout->rect );
            n_displays += 1;
        }

        SKIN_PART_LOOP_BUTTONS(part, sbutton)
            Button*  button = layout->buttons + n_buttons;
            button_init( button, sbutton, loc, back, &layout->rect, slayout );
            n_buttons += 1;
        SKIN_PART_LOOP_END
    SKIN_LAYOUT_LOOP_END

    return 0;

Fail:
    layout_done(layout);
    return -1;
}

struct SkinWindow {
    SDL_Surface*  surface;
    Layout        layout;
    SkinPos       pos;
    FingerState   finger;
    ButtonState   button;
    BallState     ball;
    char          enabled;
    char          fullscreen;
    char          no_display;

    char          enable_touch;
    char          enable_trackball;
    char          enable_dpad;
    char          enable_qwerty;

    SkinImage*    onion;
    SkinRotation  onion_rotation;
    int           onion_alpha;

    int           x_pos;
    int           y_pos;

    SkinScaler*   scaler;
    int           shrink;
    double        shrink_scale;
    unsigned*     shrink_pixels;
    SDL_Surface*  shrink_surface;

    double        effective_scale;
    double        effective_x;
    double        effective_y;
};

static void
add_finger_event(unsigned x, unsigned y, unsigned state)
{
    //fprintf(stderr, "::: finger %d,%d %d\n", x, y, state);

    /* NOTE: the 0 is used in hw/goldfish_events.c to differentiate
     * between a touch-screen and a trackball event
     */
    user_event_mouse(x, y, 0, state);
}

static void
skin_window_find_finger( SkinWindow*  window,
                         int          x,
                         int          y )
{
    FingerState*  finger = &window->finger;

    /* find the display that contains this movement */
    finger->display = NULL;
    finger->inside  = 0;

    if (!window->enable_touch)
        return;

    LAYOUT_LOOP_DISPLAYS(&window->layout,disp)
        if ( skin_rect_contains( &disp->rect, x, y ) ) {
            finger->inside   = 1;
            finger->display  = disp;
            finger->pos.x    = x - disp->origin.x;
            finger->pos.y    = y - disp->origin.y;

            skin_pos_rotate( &finger->pos, &finger->pos, -disp->rotation );
            break;
        }
    LAYOUT_LOOP_END_DISPLAYS
}

static void
skin_window_move_mouse( SkinWindow*  window,
                        int          x,
                        int          y )
{
    FingerState*  finger = &window->finger;
    ButtonState*  button = &window->button;

    if (finger->tracking) {
        ADisplay*  disp   = finger->display;
        char       inside = 1;
        int        dx     = x - disp->rect.pos.x;
        int        dy     = y - disp->rect.pos.y;

        if (dx < 0) {
            dx = 0;
            inside = 0;
        }
        else if (dx >= disp->rect.size.w) {
            dx = disp->rect.size.w - 1;
            inside = 0;
        }
        if (dy < 0) {
            dy = 0;
            inside = 0;
        } else if (dy >= disp->rect.size.h) {
            dy = disp->rect.size.h-1;
            inside = 0;
        }
        finger->inside = inside;
        finger->pos.x  = dx + (disp->rect.pos.x - disp->origin.x);
        finger->pos.y  = dy + (disp->rect.pos.y - disp->origin.y);

        skin_pos_rotate( &finger->pos, &finger->pos, -disp->rotation );
    }

    {
        Button*  hover = button->hover;

        if (hover) {
            if ( skin_rect_contains( &hover->rect, x, y ) )
                return;

            hover->down = 0;
            skin_window_redraw( window, &hover->rect );
            button->hover = NULL;
        }

        hover = NULL;
        LAYOUT_LOOP_BUTTONS( &window->layout, butt )
            if ( skin_rect_contains( &butt->rect, x, y ) ) {
                hover = butt;
                break;
            }
        LAYOUT_LOOP_END_BUTTONS

        /* filter DPAD and QWERTY buttons right here */
        if (hover != NULL) {
            switch (hover->keycode) {
                /* these correspond to the DPad */
                case kKeyCodeDpadUp:
                case kKeyCodeDpadDown:
                case kKeyCodeDpadLeft:
                case kKeyCodeDpadRight:
                case kKeyCodeDpadCenter:
                    if (!window->enable_dpad)
                        hover = NULL;
                    break;

                /* these correspond to non-qwerty buttons */
                case kKeyCodeSoftLeft:
                case kKeyCodeSoftRight:
                case kKeyCodeVolumeUp:
                case kKeyCodeVolumeDown:
                case kKeyCodePower:
                case kKeyCodeHome:
                case kKeyCodeBack:
                case kKeyCodeCall:
                case kKeyCodeEndCall:
                case kKeyCodeTV:
                case kKeyCodeEPG:
                case kKeyCodeDVR:
                case kKeyCodePrevious:
                case kKeyCodeNext:
                case kKeyCodePlay:
                case kKeyCodePause:
                case kKeyCodeStop:
                case kKeyCodeRewind:
                case kKeyCodeFastForward:
                case kKeyCodeBookmarks:
                case kKeyCodeCycleWindows:
                case kKeyCodeChannelUp:
                case kKeyCodeChannelDown:
                    break;

                /* all the rest is assumed to be qwerty */
                default:
                    if (!window->enable_qwerty)
                        hover = NULL;
            }
        }

        if (hover != NULL) {
            hover->down = 1;
            skin_window_redraw( window, &hover->rect );
            button->hover = hover;
        }
    }
}

static void
skin_window_trackball_press( SkinWindow*  window, int  down )
{
    user_event_key( BTN_MOUSE, down );
}

static void
skin_window_trackball_move( SkinWindow*  window, int  xrel, int  yrel )
{
    BallState*  state = &window->ball;

    if ( skin_trackball_move( state->ball, xrel, yrel ) ) {
        skin_trackball_refresh( state->ball );
        skin_window_redraw( window, &state->rect );
    }
}

void
skin_window_set_trackball( SkinWindow*  window, SkinTrackBall*  ball )
{
    BallState*  state = &window->ball;

    ball_state_set( state, ball );
}

void
skin_window_show_trackball( SkinWindow*  window, int  enable )
{
    BallState*  state = &window->ball;

    if (state->ball != NULL && window->enable_trackball) {
        ball_state_show(state, enable);
    }
}

/* Hide the OpenGL ES framebuffer */
static void
skin_window_hide_opengles( SkinWindow* window )
{
    android_hideOpenglesWindow();
}

/* Show the OpenGL ES framebuffer window */
static void
skin_window_show_opengles( SkinWindow* window )
{
    {
        SDL_SysWMinfo  wminfo;
        void*          winhandle;
        ADisplay*      disp = window->layout.displays;
        SkinRect       drect = disp->rect;

        memset(&wminfo, 0, sizeof(wminfo));
        SDL_GetWMInfo(&wminfo);
#ifdef _WIN32
        winhandle = (void*)wminfo.window;
#elif defined(CONFIG_DARWIN)
        winhandle = (void*)wminfo.nsWindowPtr;
#else
        winhandle = (void*)wminfo.info.x11.window;
#endif
        skin_scaler_get_scaled_rect(window->scaler, &drect, &drect);

        android_showOpenglesWindow(winhandle, drect.pos.x, drect.pos.y,
                                   drect.size.w, drect.size.h, disp->rotation * -90.);
    }
}

static void
skin_window_redraw_opengles( SkinWindow* window )
{
    android_redrawOpenglesWindow();
}

static int  skin_window_reset_internal (SkinWindow*, SkinLayout*);

SkinWindow*
skin_window_create( SkinLayout*  slayout, int  x, int  y, double  scale, int  no_display )
{
    SkinWindow*  window;

    /* If scale is <= 0, we want to check that the window's default size if
     * not larger than the current screen. Otherwise, we need to compute
     * a new scale to ensure it is.
     */
    if (scale <= 0) {
        SDL_Rect  monitor;
        int       screen_w, screen_h;
        int       win_w = slayout->size.w;
        int       win_h = slayout->size.h;
        double    scale_w, scale_h;

        /* To account for things like menu bars, window decorations etc..
         * We only compute 95% of the real screen size. */
        SDL_WM_GetMonitorRect(&monitor);
        screen_w = monitor.w * 0.95;
        screen_h = monitor.h * 0.95;

        scale_w = 1.0;
        scale_h = 1.0;

        if (screen_w < win_w && win_w > 1.)
            scale_w = 1.0 * screen_w / win_w;
        if (screen_h < win_h && win_h > 1.)
            scale_h = 1.0 * screen_h / win_h;

        scale = (scale_w <= scale_h) ? scale_w : scale_h;

        VERBOSE_PRINT(init,"autoconfig: -scale %g", scale);
    }

    ANEW0(window);

    window->shrink_scale = scale;
    window->shrink       = (scale != 1.0);
    window->scaler       = skin_scaler_create();
    window->no_display   = no_display;

    /* enable everything by default */
    window->enable_touch     = 1;
    window->enable_trackball = 1;
    window->enable_dpad      = 1;
    window->enable_qwerty    = 1;

    window->x_pos = x;
    window->y_pos = y;

    if (skin_window_reset_internal(window, slayout) < 0) {
        skin_window_free(window);
        return NULL;
    }
    SDL_WM_SetPos( x, y );

    /* Check that the window is fully visible */
    if ( !window->no_display && !SDL_WM_IsFullyVisible(0) ) {
        SDL_Rect  monitor;
        int       win_x, win_y, win_w, win_h;
        int       new_x, new_y;

        SDL_WM_GetMonitorRect(&monitor);
        SDL_WM_GetPos(&win_x, &win_y);
        win_w = window->surface->w;
        win_h = window->surface->h;

        /* First, we recenter the window */
        new_x = (monitor.w - win_w)/2;
        new_y = (monitor.h - win_h)/2;

        /* If it is still too large, we ensure the top-border is visible */
        if (new_y < 0)
            new_y = 0;

        /* Done */
        SDL_WM_SetPos(new_x, new_y);
        dprint( "emulator window was out of view and was recentered\n" );
    }

    skin_window_show_opengles(window);

    return window;
}

void
skin_window_enable_touch( SkinWindow*  window, int  enabled )
{
    window->enable_touch = !!enabled;
}

void
skin_window_enable_trackball( SkinWindow*  window, int  enabled )
{
    window->enable_trackball = !!enabled;
}

void
skin_window_enable_dpad( SkinWindow*  window, int  enabled )
{
    window->enable_dpad = !!enabled;
}

void
skin_window_enable_qwerty( SkinWindow*  window, int  enabled )
{
    window->enable_qwerty = !!enabled;
}

void
skin_window_set_title( SkinWindow*  window, const char*  title )
{
    if (window && title)
        SDL_WM_SetCaption( title, title );
}

static void
skin_window_resize( SkinWindow*  window )
{
    if ( !window->no_display )
        skin_window_hide_opengles(window);

    /* now resize window */
    if (window->surface) {
        SDL_FreeSurface(window->surface);
        window->surface = NULL;
    }

    if (window->shrink_surface) {
        SDL_FreeSurface(window->shrink_surface);
        window->shrink_surface = NULL;
    }

    if (window->shrink_pixels) {
        AFREE(window->shrink_pixels);
        window->shrink_pixels = NULL;
    }

    if ( !window->no_display ) {
        int           layout_w = window->layout.rect.size.w;
        int           layout_h = window->layout.rect.size.h;
        int           window_w = layout_w;
        int           window_h = layout_h;
        int           window_x = window->x_pos;
        int           window_y = window->y_pos;
        int           flags;
        SDL_Surface*  surface;
        double        scale = 1.0;
        int           fullscreen = window->fullscreen;

        if (fullscreen) {
            SDL_Rect  r;
            if (SDL_WM_GetMonitorRect(&r) < 0) {
                fullscreen = 0;
            } else {
                double  x_scale, y_scale;

                window_x = r.x;
                window_y = r.y;
                window_w = r.w;
                window_h = r.h;

                x_scale = window_w * 1.0 / layout_w;
                y_scale = window_h * 1.0 / layout_h;

                scale = (x_scale <= y_scale) ? x_scale : y_scale;
            }
        }
        else if (window->shrink) {
            scale = window->shrink_scale;
            window_w = (int) ceil(layout_w*scale);
            window_h = (int) ceil(layout_h*scale);
        }

        {
            char temp[32];
            sprintf(temp, "%d,%d", window_x, window_y);
            setenv("SDL_VIDEO_WINDOW_POS", temp, 1);
            setenv("SDL_VIDEO_WINDOW_FORCE_VISIBLE", "1", 1);
        }

        flags = SDL_SWSURFACE;
        if (fullscreen) {
            flags |= SDL_FULLSCREEN;
        }
        surface = SDL_SetVideoMode( window_w, window_h, 32, flags );
        if (surface == NULL) {
            fprintf(stderr, "### Error: could not create or resize SDL window: %s\n", SDL_GetError() );
            exit(1);
        }

        SDL_WM_SetPos( window_x, window_y );

        window->effective_scale = scale;
        window->effective_x     = 0;
        window->effective_y     = 0;

        if (fullscreen) {
            window->effective_x = (window_w - layout_w*scale)*0.5;
            window->effective_y = (window_h - layout_h*scale)*0.5;
        }

        if (scale == 1.0)
        {
            window->surface = surface;
            skin_scaler_set( window->scaler, 1.0, 0, 0 );
        }
        else
        {
            window_w = (int) ceil(window_w / scale );
            window_h = (int) ceil(window_h / scale );

            window->shrink_surface = surface;
            AARRAY_NEW0(window->shrink_pixels, window_w * window_h * 4);
            if (window->shrink_pixels == NULL) {
                fprintf(stderr, "### Error: could not allocate memory for rescaling surface\n");
                exit(1);
            }
            window->surface = sdl_surface_from_argb32( window->shrink_pixels, window_w, window_h );
            if (window->surface == NULL) {
                fprintf(stderr, "### Error: could not create or resize SDL window: %s\n", SDL_GetError() );
                exit(1);
            }
            skin_scaler_set( window->scaler, scale, window->effective_x, window->effective_y );
        }

        skin_window_show_opengles(window);
    }
}

static int
skin_window_reset_internal ( SkinWindow*  window, SkinLayout*  slayout )
{
    Layout         layout;
    ADisplay*      disp;

    if ( layout_init( &layout, slayout ) < 0 )
        return -1;

    layout_done( &window->layout );
    window->layout = layout;

    disp = window->layout.displays;
    if (disp != NULL && window->onion)
        display_set_onion( disp,
                           window->onion,
                           window->onion_rotation,
                           window->onion_alpha );

    skin_window_resize(window);

    finger_state_reset( &window->finger );
    button_state_reset( &window->button );
    ball_state_reset( &window->ball, window );

    skin_window_redraw( window, NULL );

    if (slayout->event_type != 0) {
        user_event_generic( slayout->event_type, slayout->event_code, slayout->event_value );
        /* XXX: hack, replace by better code here */
        if (slayout->event_value != 0)
            corecmd_set_coarse_orientation( ANDROID_COARSE_PORTRAIT );
        else
            corecmd_set_coarse_orientation( ANDROID_COARSE_LANDSCAPE );
    }

    return 0;
}

int
skin_window_reset ( SkinWindow*  window, SkinLayout*  slayout )
{
    if (!window->fullscreen) {
        SDL_WM_GetPos(&window->x_pos, &window->y_pos);
    }
    if (skin_window_reset_internal( window, slayout ) < 0)
        return -1;

    return 0;
}

void
skin_window_set_lcd_brightness( SkinWindow*  window, int  brightness )
{
    ADisplay*  disp = window->layout.displays;

    if (disp != NULL) {
        disp->brightness = brightness;
        skin_window_redraw( window, NULL );
    }
}

void
skin_window_free  ( SkinWindow*  window )
{
    if (window) {
        if (window->surface) {
            SDL_FreeSurface(window->surface);
            window->surface = NULL;
        }
        if (window->shrink_surface) {
            SDL_FreeSurface(window->shrink_surface);
            window->shrink_surface = NULL;
        }
        if (window->shrink_pixels) {
            AFREE(window->shrink_pixels);
            window->shrink_pixels = NULL;
        }
        if (window->onion) {
            skin_image_unref( &window->onion );
            window->onion_rotation = SKIN_ROTATION_0;
        }
        if (window->scaler) {
            skin_scaler_free(window->scaler);
            window->scaler = NULL;
        }
        layout_done( &window->layout );
        AFREE(window);
    }
}

void
skin_window_set_onion( SkinWindow*   window,
                       SkinImage*    onion,
                       SkinRotation  onion_rotation,
                       int           onion_alpha )
{
    ADisplay*  disp;
    SkinImage*  old = window->onion;

    window->onion          = skin_image_ref(onion);
    window->onion_rotation = onion_rotation;
    window->onion_alpha    = onion_alpha;

    skin_image_unref( &old );

    disp = window->layout.displays;

    if (disp != NULL)
        display_set_onion( disp, window->onion, onion_rotation, onion_alpha );
}

static void
skin_window_update_shrink( SkinWindow*  window, SkinRect*  rect )
{
    skin_scaler_scale( window->scaler, window->shrink_surface, window->surface,
                       rect->pos.x, rect->pos.y, rect->size.w, rect->size.h );
}

void
skin_window_set_scale( SkinWindow*  window, double  scale )
{
    window->shrink       = (scale != 1.0);
    window->shrink_scale = scale;

    skin_window_resize( window );
    skin_window_redraw( window, NULL );
}

void
skin_window_redraw( SkinWindow*  window, SkinRect*  rect )
{
    if (window != NULL && window->surface != NULL) {
        Layout*  layout = &window->layout;

        if (rect == NULL)
            rect = &layout->rect;

        {
            SkinRect  r;

            if ( skin_rect_intersect( &r, rect, &layout->rect ) ) {
                SDL_Rect  rd;
                rd.x = r.pos.x;
                rd.y = r.pos.y;
                rd.w = r.size.w;
                rd.h = r.size.h;

                SDL_FillRect( window->surface, &rd, layout->color );
            }
        }

        {
            Background*  back = layout->backgrounds;
            Background*  end  = back + layout->num_backgrounds;
            for ( ; back < end; back++ )
                background_redraw( back, rect, window->surface );
        }

        {
            ADisplay*  disp = layout->displays;
            ADisplay*  end  = disp + layout->num_displays;
            for ( ; disp < end; disp++ )
                display_redraw( disp, rect, window->surface );
        }

        {
            Button*  button = layout->buttons;
            Button*  end    = button + layout->num_buttons;
            for ( ; button < end; button++ )
                button_redraw( button, rect, window->surface );
        }

        if ( window->ball.tracking )
            ball_state_redraw( &window->ball, rect, window->surface );

        if (window->effective_scale != 1.0)
            skin_window_update_shrink( window, rect );
        else
        {
            SDL_Rect  rd;
            rd.x = rect->pos.x;
            rd.y = rect->pos.y;
            rd.w = rect->size.w;
            rd.h = rect->size.h;

            SDL_UpdateRects( window->surface, 1, &rd );
        }
        skin_window_redraw_opengles( window );
    }
}

void
skin_window_toggle_fullscreen( SkinWindow*  window )
{
    if (window && window->surface) {
        if (!window->fullscreen)
            SDL_WM_GetPos( &window->x_pos, &window->y_pos );

        window->fullscreen = !window->fullscreen;
        skin_window_resize( window );
        skin_window_redraw( window, NULL );
    }
}

void
skin_window_get_display( SkinWindow*  window, ADisplayInfo  *info )
{
    ADisplay*  disp = window->layout.displays;

    if (disp != NULL) {
        info->width    = disp->datasize.w;
        info->height   = disp->datasize.h;
        info->rotation = disp->rotation;
        info->data     = disp->data;
    } else {
        info->width    = 0;
        info->height   = 0;
        info->rotation = SKIN_ROTATION_0;
        info->data     = NULL;
    }
}


static void
skin_window_map_to_scale( SkinWindow*  window, int  *x, int  *y )
{
    *x = (*x - window->effective_x) / window->effective_scale;
    *y = (*y - window->effective_y) / window->effective_scale;
}

void
skin_window_process_event( SkinWindow*  window, SDL_Event*  ev )
{
    Button*  button;
    int      mx, my;

    if (!window->surface)
        return;

    switch (ev->type) {
    case SDL_MOUSEBUTTONDOWN:
        if ( window->ball.tracking ) {
            skin_window_trackball_press( window, 1 );
            break;
        }

        mx = ev->button.x;
        my = ev->button.y;
        skin_window_map_to_scale( window, &mx, &my );
        skin_window_move_mouse( window, mx, my );
        skin_window_find_finger( window, mx, my );
#if 0
        printf("down: x=%d y=%d fx=%d fy=%d fis=%d\n",
               ev->button.x, ev->button.y, window->finger.pos.x,
               window->finger.pos.y, window->finger.inside);
#endif
        if (window->finger.inside) {
            window->finger.tracking = 1;
            add_finger_event(window->finger.pos.x, window->finger.pos.y, 1);
        } else {
            window->button.pressed = NULL;
            button = window->button.hover;
            if(button) {
                button->down += 1;
                skin_window_redraw( window, &button->rect );
                window->button.pressed = button;
                if(button->keycode) {
                    user_event_key(button->keycode, 1);
                }
            }
        }
        break;

    case SDL_MOUSEBUTTONUP:
        if ( window->ball.tracking ) {
            skin_window_trackball_press( window, 0 );
            break;
        }
        button = window->button.pressed;
        mx = ev->button.x;
        my = ev->button.y;
        skin_window_map_to_scale( window, &mx, &my );
        if (button)
        {
            button->down = 0;
            skin_window_redraw( window, &button->rect );
            if(button->keycode) {
                user_event_key(button->keycode, 0);
            }
            window->button.pressed = NULL;
            window->button.hover   = NULL;
            skin_window_move_mouse( window, mx, my );
        }
        else if (window->finger.tracking)
        {
            skin_window_move_mouse( window, mx, my );
            window->finger.tracking = 0;
            add_finger_event( window->finger.pos.x, window->finger.pos.y, 0);
        }
        break;

    case SDL_MOUSEMOTION:
        if ( window->ball.tracking ) {
            skin_window_trackball_move( window, ev->motion.xrel, ev->motion.yrel );
            break;
        }
        mx = ev->button.x;
        my = ev->button.y;
        skin_window_map_to_scale( window, &mx, &my );
        if ( !window->button.pressed )
        {
            skin_window_move_mouse( window, mx, my );
            if ( window->finger.tracking ) {
                add_finger_event( window->finger.pos.x, window->finger.pos.y, 1 );
            }
        }
        break;

    case SDL_VIDEOEXPOSE:
        skin_window_redraw_opengles(window);
        break;
    }
}

static ADisplay*
skin_window_display( SkinWindow*  window )
{
    return window->layout.displays;
}

void
skin_window_update_display( SkinWindow*  window, int  x, int  y, int  w, int  h )
{
    ADisplay*  disp = skin_window_display(window);

    if ( !window->surface )
        return;

    if (disp != NULL) {
        SkinRect  r;
        r.pos.x  = x;
        r.pos.y  = y;
        r.size.w = w;
        r.size.h = h;

        skin_rect_rotate( &r, &r, disp->rotation );
        r.pos.x += disp->origin.x;
        r.pos.y += disp->origin.y;

        if (window->effective_scale != 1.0)
            skin_window_redraw( window, &r );
        else
            display_redraw( disp, &r, window->surface );
    }
}
