/* Copyright (C) 2007-2015 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/config/config.h"
#include "android/crashreport/crash-handler.h"
#include "android/multitouch-screen.h"
#include "android/skin/charmap.h"
#include "android/skin/event.h"
#include "android/skin/image.h"
#include "android/skin/winsys.h"
#include "android/utils/debug.h"
#include "android/utils/setenv.h"
#include "android/utils/system.h"
#include "android/utils/duff.h"

#include <math.h>
#include <stdio.h>
#include <stdlib.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, SkinSurface* surface)
{
    SkinRect  r;

    if (skin_rect_intersect( &r, rect, &back->rect ) )
    {
        SkinRect src_rect;
        src_rect.pos.x = r.pos.x - back->origin.x;
        src_rect.pos.y = r.pos.y - back->origin.y;
        src_rect.size = r.size;

        skin_surface_blit(surface,
                          &r.pos,
                          skin_image_surface(back->image),
                          &src_rect,
                          SKIN_BLIT_SRCOVER);
    }
}


typedef struct ADisplay {
    SkinRect       rect;
    SkinPos        origin;
    SkinRotation   rotation;
    SkinSize       datasize;  /* framebuffer size */
    void*          data;      /* framebuffer pixels */
    int            bits_per_pixel;  /* framebuffer depth */
    SkinImage*     onion;       /* onion image */
    SkinRect       onion_rect;  /* onion rect, if any */
    int            brightness;
    void*          gpu_frame;   /* GL_RGBA, datasize.w * datasize.h * 4 bytes */
    SkinSurface*   surface;     /* displayed surface after rotation + onion */
} ADisplay;

static void adisplay_done(ADisplay* disp) {
    if (disp->gpu_frame) {
        free(disp->gpu_frame);
        disp->gpu_frame = NULL;
    }

    skin_surface_unrefp(&disp->surface);
    disp->data = NULL;
    skin_image_unref(&disp->onion);
}

static int adisplay_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;

        case SKIN_ROTATION_270:
            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->data = NULL;
    disp->bits_per_pixel = 0;
    if (sdisp->framebuffer_funcs) {
        disp->data =
                sdisp->framebuffer_funcs->get_pixels(sdisp->framebuffer);
        disp->bits_per_pixel =
                sdisp->framebuffer_funcs->get_depth(sdisp->framebuffer);
    }
    disp->onion  = NULL;

    disp->brightness = LCD_BRIGHTNESS_DEFAULT;

    disp->gpu_frame = NULL;

    disp->surface = skin_surface_create(disp->rect.size.w,
                                        disp->rect.size.h,
                                        disp->rect.size.w,
                                        disp->rect.size.h);

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

static __inline__ uint32_t rgb565_to_argb32(uint32_t pix) {
#if 1
    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 << 16) | (g8 << 8) | (b8 << 0) | 0xff000000U;
#else
    uint32_t r8 = ((pix & 0xf800) << 8) | ((pix & 0xe000) >> 5);
    uint32_t g8 = ((pix & 0x07e0) << 5) | ((pix & 0x0600) >> 1);
    uint32_t b8 = ((pix & 0x001f) <<  3) | ((pix & 0x001c) >>  2);
    return r8 | g8 | b8 | 0xff000000U;
#endif
}

static void adisplay_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;

        case SKIN_ROTATION_270:
            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;
}

// Set to 1 to enable experimental dot-matrix display mode.
#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(uint32_t* pixels,
                                  int w,
                                  int h,
                                  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;

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

    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 / sizeof(uint32_t));
        }
    }
    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 / sizeof(uint32_t));
        }
    }
}

static void adisplay_update_surface_pixels_16(ADisplay* disp,
                                              SkinRect* dst_rect,
                                              uint8_t* dst_pixels,
                                              int dst_pitch) {
    int           x  = dst_rect->pos.x;
    int           y  = dst_rect->pos.y;
    int           w  = dst_rect->size.w;
    int           h  = dst_rect->size.h;
    int           src_w    = disp->datasize.w;
    int           src_h    = disp->datasize.h;
    int           src_pitch = src_w * 2;
    uint8_t*      src_line  = (uint8_t*)disp->data;
    uint8_t*      dst_line  = dst_pixels;
    int           yy, xx;

    switch ( disp->rotation & 3 )
    {
    case SKIN_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_argb32(src[xx]);
                xx++;
            });
            src_line += src_pitch;
            dst_line += dst_pitch;
        }
        break;

    case SKIN_ROTATION_90:
        src_line += (y * 2) + ((src_h - 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_argb32(((uint16_t*)src)[0]);
                src -= src_pitch;
                dst += 1;
            });
            src_line += 2;
            dst_line += dst_pitch;
        }
        break;

    case SKIN_ROTATION_180:
        src_line += ((src_w - 1 - x) * 2) + ((src_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_argb32(src[0]);
                src -= 1;
                dst += 1;
            });
            src_line -= src_pitch;
            dst_line += dst_pitch;
    }
    break;

    default:  /* SKIN_ROTATION_270 */
        src_line += ((src_w - 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_argb32(((uint16_t*)src)[0]);
                dst += 1;
                src += src_pitch;
            });
            src_line -= 2;
            dst_line += dst_pitch;
        }
    }
}

static void adisplay_update_surface_pixels_32(ADisplay* disp,
                                              SkinRect* rect,
                                              uint8_t* dst_pixels,
                                              int dst_pitch,
                                              const void* src_pixels) {
    int           x  = rect->pos.x;
    int           y  = rect->pos.y;
    int           w  = rect->size.w;
    int           h  = rect->size.h;
    int           src_w     = disp->datasize.w;
    int           src_h     = disp->datasize.h;
    uint8_t*      dst_line  = dst_pixels;
    int           src_pitch = disp->datasize.w * 4;
    const uint8_t* src_line  = (const uint8_t*)src_pixels;
    int           yy;

    switch ( disp->rotation & 3 )
    {
    case SKIN_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] = src[0];
                dst++;
                src++;
            });
            src_line += src_pitch;
            dst_line += dst_pitch;
        }
        break;

    case SKIN_ROTATION_90:
        src_line += (y * 4) + ((src_h - x - 1) * src_pitch);

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

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

    case SKIN_ROTATION_180:
        src_line += ((src_w - 1 - x) * 4) + ((src_h - 1 - y) * src_pitch);

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

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

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

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

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

struct local_pixels_buffer_t {
    uint8_t* pixels;
    int size;
};

static struct local_pixels_buffer_t local_pixels_buffer = {.pixels = NULL, .size = 0};

static uint8_t* local_calloc(int size) {
    if (local_pixels_buffer.pixels == NULL) {
        local_pixels_buffer.pixels = calloc(1, size);
        local_pixels_buffer.size = size;
    } else if (local_pixels_buffer.size < size) {
        local_pixels_buffer.size = size > 2 * local_pixels_buffer.size ?
                                      size : 2 * local_pixels_buffer.size;
        free(local_pixels_buffer.pixels);
        local_pixels_buffer.pixels = calloc(1, local_pixels_buffer.size);
    }
    return local_pixels_buffer.pixels;
}

// Update the content of the display surface from the framebuffer content.
// |disp| is the target ADisplay instance.
// |rect| is the rectangle to update, in coordinates relative to the
// display surface, i.e. (0,0) is always the top-left corner.
static void adisplay_update_surface(ADisplay* disp,
                                    SkinRect* rect) {
    int x = rect->pos.x;
    int y = rect->pos.y;
    int w = rect->size.w;
    int h = rect->size.h;

    // Clip update rectangle for sanity.
    int delta = (x + w) - disp->rect.size.w;
    if (delta > 0) {
        w -= delta;
    }
    if (x < 0) {
        w += x;
        x = 0;
    }
    delta = (y + h) - disp->rect.size.h;
    if (delta > 0) {
        h -= delta;
    }
    if (y < 0) {
        h += delta;
        y = 0;
    }
    if (w <= 0 || h <= 0) {
        return;  // nothing to do.
    }

    // Allocate a temporary buffer to get the potentially rotated / converted
    // content.
    int sz = disp->datasize.h > disp->datasize.w ? disp->datasize.h : disp->datasize.w;
    int dst_pitch = 4 * sz;
    const int size = sz * dst_pitch;
    uint8_t* dst_pixels = local_calloc(size);
    if (dst_pixels == NULL) {
        derror("ERROR: %s:%d cannot allocate memory of %d bytes.\n",
               __func__, __LINE__, size);
        crashhandler_die_format(
                    "Display surface memory allocation failed "
                    "(requested %d bytes)",
                    size);
    }

    SkinRect dst_r = {
        .pos.x = x,
        .pos.y = y,
        .size.w = w,
        .size.h = h };

    if (disp->gpu_frame) {
        // Content comes from the emulated GPU.
        adisplay_update_surface_pixels_32(
                disp, &dst_r, dst_pixels, dst_pitch, disp->gpu_frame);
    } else {
        // Content comes from the emulated framebuffer.
        if (disp->bits_per_pixel == 32) {
            adisplay_update_surface_pixels_32(
                    disp, &dst_r, dst_pixels, dst_pitch, disp->data);
        } else {
            adisplay_update_surface_pixels_16(
                    disp, &dst_r, dst_pixels, dst_pitch);
        }
    }

    // Apply brightness modulation.
    lcd_brightness_argb32((uint32_t*)dst_pixels,
                          disp->datasize.w,
                          disp->datasize.h,
                          dst_pitch,
                          disp->brightness);

    // Update the display surface content
    skin_surface_upload(disp->surface, &dst_r, dst_pixels, dst_pitch);

    // Done
}

static void adisplay_redraw(ADisplay* disp,
                            SkinRect* rect,
                            SkinSurface* surface,
                            bool using_emugl_subwindow) {
    SkinRect  r;

    if (!skin_rect_intersect(&r, rect, &disp->rect)) {
        return;
    }

#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

    // Update the content of the display surface.
    SkinRect src_r = r;
    src_r.pos.x -= disp->rect.pos.x;
    src_r.pos.y -= disp->rect.pos.y;
    if (!using_emugl_subwindow) {
        adisplay_update_surface(disp, &src_r);
    }

    if (disp->brightness == LCD_BRIGHTNESS_OFF) {
        // Fill window surface with solid black.
        skin_surface_fill(surface, &r, 0xff000000);
    } else {
        skin_surface_blit(surface,
                          &r.pos,
                          disp->surface,
                          &src_r,
                          SKIN_BLIT_COPY);
    }

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

        if ( skin_rect_intersect( &r2, &r, &disp->onion_rect ) ) {
            SkinRect src_rect;
            src_rect.pos.x = r2.pos.x - disp->onion_rect.pos.x;
            src_rect.pos.y = r2.pos.y - disp->onion_rect.pos.y;
            src_rect.size = r2.size;

            skin_surface_blit(surface,
                                &r2.pos,
                                skin_image_surface(disp->onion),
                                &src_rect,
                                SKIN_BLIT_SRCOVER);
        }
    }

    skin_surface_update(surface, &r);
}


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 = skin_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, SkinSurface* surface)
{
    SkinRect  r;

    if (skin_rect_intersect( &r, rect, &button->rect ))
    {
        if ( button->down && button->image != SKIN_IMAGE_NONE )
        {
            SkinRect src_rect;
            src_rect.pos.x = r.pos.x - button->origin.x;
            src_rect.pos.y = r.pos.y - button->origin.y;
            src_rect.size = r.size;

            if (button->image != SKIN_IMAGE_NONE) {
                skin_surface_blit(surface,
                                  &r.pos,
                                  skin_image_surface(button->image),
                                  &src_rect,
                                  SKIN_BLIT_SRCOVER);
                if (button->down > 1) {
                    skin_surface_blit(surface,
                                      &r.pos,
                                      skin_image_surface(button->image),
                                      &src_rect,
                                      SKIN_BLIT_SRCOVER);
                }
            }
        }
    }
}


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, SkinSurface* 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;
            skin_trackball_refresh( state->ball );
            skin_window_redraw( state->window, &state->rect );
        }
    } else {
        if ( state->tracking ) {
            state->tracking = 0;
            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) {
        skin_trackball_rect(ball, &state->rect);
    }
}

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++)
        adisplay_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;
            (void)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;
            adisplay_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 {
    const SkinWindowFuncs* win_funcs;
    SkinSurface*  surface;
    Layout        layout;
    SkinPos       pos;
    FingerState   finger;
    FingerState   secondary_finger;
    ButtonState   button;
    BallState     ball;
    bool          use_emugl_subwindow;

    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;
    double        scale;

    // Zoom-related parameters
    double        zoom;
    SkinRect      subwindow;
    SkinPos       subwindow_original;
    SkinSize      framebuffer;
    SkinSize      container;
    int           scroll_h; // Needed for OSX
};

static void
add_finger_event(SkinWindow* window,
                 unsigned x,
                 unsigned y,
                 unsigned state)
{
    window->win_funcs->mouse_event(x, y, state);
}

static void
skin_window_find_finger( SkinWindow*  window,
                         FingerState* finger,
                         int          x,
                         int          y )
{
    /* 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,
                        FingerState* finger,
                        int          x,
                        int          y )
{
    ButtonState*  button = &window->button;

    if (finger->tracking && finger->display) {
        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 kKeyCodeHomePage:
                case kKeyCodeBack:
                case kKeyCodeCall:
                case kKeyCodeEndCall:
                case kKeyCodeTV:
                case kKeyCodeEPG:
                case kKeyCodeDVR:
                case kKeyCodePrevious:
                case kKeyCodeNext:
                case kKeyCodePlay:
                case kKeyCodePlaypause:
                case kKeyCodePause:
                case kKeyCodeStop:
                case kKeyCodeRewind:
                case kKeyCodeFastForward:
                case kKeyCodeBookmarks:
                case kKeyCodeCycleWindows:
                case kKeyCodeChannelUp:
                case kKeyCodeChannelDown:
                case kKeyCodeAppSwitch:
                    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 )
{
    window->win_funcs->key_event(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 )
{
    window->win_funcs->opengles_hide();
    //android_hideOpenglesWindow();
}

typedef struct {
    SkinWindow* window;
    void* handle;
    int wx;
    int wy;
    int ww;
    int wh;
    int fbw;
    int fbh;
    float dpr;
    float rot;
} gles_show_data;

static void skin_window_run_opengles_show(void* p) {
    const gles_show_data* data = (const gles_show_data*)p;
    data->window->win_funcs->opengles_show(data->handle,
                                           data->wx,
                                           data->wy,
                                           data->ww,
                                           data->wh,
                                           data->fbw,
                                           data->fbh,
                                           data->dpr,
                                           data->rot);
}

static void
skin_window_setup_opengles_subwindow( SkinWindow* window, gles_show_data* data)
{
    data->window = window;
    data->wx = window->subwindow.pos.x;
    data->wy = window->subwindow.pos.y;
    data->ww = window->subwindow.size.w;
    data->wh = window->subwindow.size.h;

    data->fbw = window->framebuffer.w;
    data->fbh = window->framebuffer.h;
    data->dpr = 1.0;

#if defined(__APPLE__)
    // If the window is on a retina monitor, the framebuffer size needs to be
    // adjusted to the actual number of pixels.
    double dpr;
    if (skin_winsys_get_device_pixel_ratio(&dpr) == 0) {
        data->dpr = dpr;
    }

    // The native GL subwindow for OSX (using Cocoa) uses cartesian (y-up) coordinates. We
    // have code to transform window (y-down) coordinates into cartesian coordinates at that
    // level, but Qt seems to do this transformation on its own. This means the transformation
    // is done *twice* with Qt + OSX, resulting in the incorrect y value. The following "undoes"
    // the transformation by doing it a third time. Additionally, because the scroll bar now
    // affects the relative coordinate system inside the window, it must be taken into account
    // as well. At the end of this function, data->wy will equal the bottom coordinate of the
    // subwindow (in units from the bottom of the overall window) if this is the Qt OSX emulator.
    data->wy = window->container.h - (data->wy + data->wh);
    data->wy += window->scroll_h;
#endif  // __APPLE__
}

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

    gles_show_data data;
    skin_window_setup_opengles_subwindow(window, &data);

    data.handle = winhandle;
    data.rot = disp->rotation * 90.;

    skin_winsys_run_ui_update(&skin_window_run_opengles_show, &data);
}

static void
skin_window_redraw_opengles( SkinWindow* window )
{
    window->win_funcs->opengles_redraw();
    //android_redrawOpenglesWindow();
}

static int  skin_window_reset_internal (SkinWindow*, SkinLayout*);

SkinWindow* skin_window_create(SkinLayout* slayout,
                               int x,
                               int y,
                               bool enable_scale,
                               bool use_emugl_subwindow,
                               const SkinWindowFuncs* win_funcs) {
    SkinWindow*  window;

    ANEW0(window);

    window->win_funcs    = win_funcs;
    window->use_emugl_subwindow = use_emugl_subwindow;
    window->surface = NULL;

    /* 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;
    window->scroll_h = 0;

    SkinRect  monitor;
    int       win_w = slayout->size.w;
    int       win_h = slayout->size.h;
    double    scale_w = 1.0;
    double    scale_h = 1.0;

    skin_winsys_get_monitor_rect(&monitor);

    // Make the default scale about 80% of the screen size.
    if (enable_scale && monitor.size.w < win_w && win_w > 1.)
        scale_w = 0.80 * monitor.size.w / win_w;
    if (enable_scale && monitor.size.h < win_h && win_h > 1.)
        scale_h = 0.80 * monitor.size.h / win_h;

    window->scale = (scale_w <= scale_h) ? scale_w : scale_h;

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

    /* Check that the window is fully visible */
    if (enable_scale && !skin_winsys_is_window_fully_visible()) {
        int win_x, win_y, win_w, win_h;
        int new_x, new_y;

        skin_winsys_get_window_pos(&win_x, &win_y);
        win_w = skin_surface_width(window->surface);
        win_h = skin_surface_height(window->surface);

        VERBOSE_PRINT(init, "Window was not fully visible: "
                "monitor=[%d,%d,%d,%d] window=[%d,%d,%d,%d]",
                monitor.pos.x,
                monitor.pos.y,
                monitor.size.w,
                monitor.size.h,
                win_x,
                win_y,
                win_w,
                win_h);

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

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

        VERBOSE_PRINT(init, "Window repositioned to [%d,%d]", new_x, new_y);

        /* Done */
        skin_winsys_set_window_pos(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) {
        skin_winsys_set_window_title(title);
    }
}

void
skin_window_position_changed( SkinWindow* window, int x, int y )
{
    window->x_pos = x;
    window->y_pos = y;
}

int
skin_window_recompute_subwindow_rect( SkinWindow* window, SkinRect* subwindow )
{
    // The full subwindow must be intersected with the container to compute the actual subwindow
    SkinRect result;

    SkinRect container;
    container.pos.x = 0;
    container.pos.y = 0;
    container.size.w = window->container.w;
    container.size.h = window->container.h;

    // If the emulator window is so small that the native subwindow wouldn't even appear,
    // force the subwindow to at least have positive size, else the native window managers
    // may crash. For example, on Linux, X11 crashes when told to create a window with 0 size.
    if (!skin_rect_intersect(&result, subwindow, &container)) {
        result.size.w = 1;
        result.size.h = 1;
    }

    if (skin_rect_equals(&window->subwindow, &result)) {
        return 0;
    }

    window->subwindow.pos.x = result.pos.x;
    window->subwindow.pos.y = result.pos.y;
    window->subwindow.size.w = result.size.w;
    window->subwindow.size.h = result.size.h;

    skin_winsys_set_device_geometry(&window->subwindow);

    return 1;
}

void
skin_window_scroll_updated( SkinWindow* window, int dx, int xmax, int dy, int ymax )
{
    // Pretend the subwindow has moved by the appropriate amount
    SkinRect subwindow;
    subwindow.pos.x = window->subwindow_original.x - dx;
    subwindow.pos.y = window->subwindow_original.y - dy;
    subwindow.size.w = window->framebuffer.w;
    subwindow.size.h = window->framebuffer.h;

    skin_window_recompute_subwindow_rect(window, &subwindow);
    skin_window_show_opengles(window);

    // Compute the margins around the sub-window, then transform the current scroll values
    // to take into account these margins.
    int left_buf = window->subwindow_original.x;
    int right_buf = skin_surface_width(window->surface)
                        - (window->framebuffer.w + left_buf);
    float px;
    if (left_buf + right_buf >= xmax) {
        // The subwindow fits entirely in the container, so there are no intermediate translations
        px = dx < left_buf ? 0 : 1;
    } else {
        px = (float) (dx - left_buf) / (float) (xmax - (left_buf + right_buf));
    }

    int top_buf = window->subwindow_original.y;
    int bottom_buf = skin_surface_height(window->surface)
                         - (window->framebuffer.h + top_buf);
    float py;
    if (top_buf + bottom_buf >= ymax) {
        // The subwindow fits entirely in the container, so there are no intermediate translations
        py = dy < top_buf ? 1 : 0;
    } else {
        // Use (ymax - dy) instead of (dy) since OGL coordinates are Y-up
        py = (float) ((ymax - dy) - bottom_buf) / (float) (ymax - (bottom_buf + top_buf));
    }

    // Clamp the values to [0,1]. (dx,dy) = (0,0) indicates to align the bottom left corner of the
    // framebuffer with the bottom left corner of the subwindow. (1,1) indicates to align the
    // top right corner of the framebuffer with the top right corner of the subwindow. All
    // intermediate values are an interpolation between these two states.
    px = px > 1 ? 1 : (px < 0 ? 0 : px);
    py = py > 1 ? 1 : (py < 0 ? 0 : py);

    window->win_funcs->opengles_setTranslation(px, py);
}

static void
skin_window_resize( SkinWindow*  window, int resize_container )
{
    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;
    double        scale = window->scale;

    // Pre-record the container dimensions
    if (resize_container) {
        window->container.w = (int) ceil(layout_w * scale);
        window->container.h = (int) ceil(layout_h * scale);
    }

    if (window->zoom != 1.0) {
        scale *= window->zoom;
    }

    if (scale != 1.0) {
        window_w = (int) ceil(layout_w * scale);
        window_h = (int) ceil(layout_h * scale);
    }

    // Attempt to resize the window surface. If it doesn't exist, a new one will be
    // allocated. If it does exist, but it's original dimensions do not match the new
    // ones, it will be de-allocated and a new one will be returned.
    window->surface = skin_surface_resize(window->surface,
                                          window_w, window_h,
                                          layout_w, layout_h);

    // Force redraw the background and skin to avoid drawing empty frames. This reduces flicker
    // on resize and rotate.
    Layout* layout = &window->layout;
    skin_surface_fill(window->surface,
                      &layout->rect,
                      layout->color);

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

    skin_surface_create_window(window->surface, window_x, window_y,
                               window_w, window_h);

    // Calculate the framebuffer and window sizes and locations
    ADisplay* disp = window->layout.displays;
    SkinRect drect = disp->rect;
    skin_surface_get_scaled_rect(window->surface, &drect, &drect);

    // Store original values to use for scrolling later
    window->subwindow_original.x = drect.pos.x;
    window->subwindow_original.y = drect.pos.y;

    window->framebuffer.w = drect.size.w;
    window->framebuffer.h = drect.size.h;

    if (skin_window_recompute_subwindow_rect(window, &drect) && resize_container) {
        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;

    // Reset viewport parameters
    window->zoom = 1.0;
    window->scroll_h = 0;
    window->framebuffer.w = 0;
    window->framebuffer.h = 0;

    // Resetting the subwindow parameters ensures that a proper resizing of
    // the native subwindow actually occurs. Without this, it is possible for
    // a rotation to not reach the subwindow (for example, in the case of a
    // square watch skin, which might have two layouts with *exactly* the same
    // subwindow).
    window->subwindow.pos.x = -1;
    window->subwindow.pos.y = -1;
    window->subwindow.size.w = 0;
    window->subwindow.size.h = 0;

    disp = window->layout.displays;
    if (disp != NULL) {
        if (slayout->onion_image) {
            // Onion was specified in layout file.
            adisplay_set_onion(disp,
                               slayout->onion_image,
                               slayout->onion_rotation,
                               slayout->onion_alpha );
        } else if (window->onion) {
            // Onion was specified via command line.
            adisplay_set_onion(disp,
                               window->onion,
                               window->onion_rotation,
                               window->onion_alpha );
        }
    }

    skin_window_resize(window, 1);

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

    skin_window_redraw( window, NULL );

    if ( layout.displays ) {
        // TODO(grigoryj): debug output for investigating the rotation bug.
        if (VERBOSE_CHECK(rotation)) {
            fprintf(stderr, "Setting device orientation %d\n", layout.displays->rotation);
        }
        window->win_funcs->set_device_orientation(layout.displays->rotation);
    }

    return 0;
}

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

    return 0;
}

void
skin_window_zoomed_window_resized( SkinWindow* window, int dx, int dy, int w, int h, int scroll_h )
{
    // Pretend the subwindow has moved by the appropriate amount
    SkinRect subwindow;
    subwindow.pos.x = window->subwindow_original.x - dx;
    subwindow.pos.y = window->subwindow_original.y - dy;
    subwindow.size.w = window->framebuffer.w;
    subwindow.size.h = window->framebuffer.h;

    window->container.w = w;
    window->container.h = h;
    window->scroll_h = scroll_h;

    if (skin_window_recompute_subwindow_rect(window, &subwindow)) {
        skin_window_show_opengles(window);
        skin_window_redraw_opengles(window);
    }
}

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) {
        skin_surface_unrefp(&window->surface);

        if (window->onion) {
            skin_image_unref(&window->onion);
            window->onion_rotation = SKIN_ROTATION_0;
        }
        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)
        adisplay_set_onion(disp, window->onion, onion_rotation, onion_alpha);
}

void
skin_window_set_scale(SkinWindow* window, double scale)
{
    window->scale = scale;

    // The scroll bars *will* be gone if this function is called, so make sure
    // they are not taken into account when resizing the window.
    window->scroll_h = 0;
    window->zoom = 1.0;      // Scaling the window should reset all "viewport" parameters

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

void
skin_window_set_zoom(SkinWindow* window, double zoom, int dw, int dh, int scroll_h)
{
    // Pre-record the container dimensions
    window->container.w = dw;
    window->container.h = dh;
    window->scroll_h = scroll_h;
    window->zoom = zoom;

    skin_window_resize( window, 0 );
    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 ) ) {
                skin_surface_fill(window->surface,
                                  &r,
                                  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++) {
                adisplay_redraw(disp, rect, window->surface,
                                window->use_emugl_subwindow);
            }
        }

        {
            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 );

        skin_surface_update(window->surface, rect);
        skin_window_redraw_opengles( window );
    }
}

static void
skin_window_map_to_scale( SkinWindow*  window, int  *x, int  *y )
{
    skin_surface_reverse_map(window->surface, x, y);
}

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

    // This button state set will still be interpreted correctly for
    // single-touch, which only uses the first bit.
    int button_state = multitouch_create_buttons_state(
            ev->type != kEventMouseButtonUp, ev->u.mouse.skip_sync,
            ev->u.mouse.button);

    FingerState* finger;
    if (ev->u.mouse.button == kMouseButtonSecondaryTouch) {
        finger = &window->secondary_finger;
    } else {
        finger = &window->finger;
    }

    if (!window->surface)
        return;

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

        mx = ev->u.mouse.x;
        my = ev->u.mouse.y;
        skin_window_map_to_scale( window, &mx, &my );
        skin_window_move_mouse( window, finger, mx, my );
        skin_window_find_finger( window, finger, mx, my );
#if 0
        printf("down: x=%d y=%d fx=%d fy=%d fis=%d\n",
               ev->u.mouse.x, ev->u.mouse.y, window->finger.pos.x,
               window->finger.pos.y, window->finger.inside);
#endif
        if (finger->inside) {
            finger->tracking = 1;
            add_finger_event(window,
                             finger->pos.x,
                             finger->pos.y,
                             button_state);
        } 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) {
                    window->win_funcs->key_event(button->keycode, 1);
                }
            }
        }
        break;

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

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

    case kEventScreenChanged:
        // Re-setup the OpenGL ES subwindow with a potentially different
        // framebuffer size (e.g., 2x for retina screens).
        skin_window_hide_opengles(window);
        skin_window_show_opengles(window);
        break;

    default:
        ;
    }

}

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 )
{
    if ( !window->surface )
        return;

    ADisplay* disp = skin_window_display(window);

    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;

        adisplay_redraw(disp, &r, window->surface, window->use_emugl_subwindow);
    }
}


void skin_window_update_gpu_frame(SkinWindow* window,
                                  int w,
                                  int h,
                                  const void* pixels) {
    if (!window) {
        return;
    }

    ADisplay* disp = skin_window_display(window);
    if (!disp || disp->datasize.w != w || disp->datasize.h != h) {
        fprintf(stderr, "%s: bad values!\n", __FUNCTION__);
        return;
    }

    if (!disp->gpu_frame) {
        const int size = 4 * w * h;
        disp->gpu_frame = calloc(1, size);
        if (!disp->gpu_frame) {
            derror("ERROR: %s:%d cannot allocate memory of %d bytes.\n",
                   __func__, __LINE__, size);
            crashhandler_die_format(
                    "GPU frame memory allocation failed (requested %d bytes)",
                    size);
        }
    }
    // Convert from GL_RGBA to 32-bit ARGB.
    {
        const uint8_t* src = pixels;
        uint32_t* dst = (uint32_t*)disp->gpu_frame;
        uint32_t* dst_end = dst + w * h;
        for (; dst < dst_end; src += 4, dst += 1) {
            dst[0] = ((uint32_t)src[3] << 24) |
                     ((uint32_t)src[0] << 16) |
                     ((uint32_t)src[1] << 8) |
                      (uint32_t)src[2];
        }
    }

    skin_window_update_display(window, 0, 0, w, h);
}
