/*
 * Window related functions
 *
 * Copyright 1993, 1994, 1995, 1996, 2001, 2013-2017 Alexandre Julliard
 * Copyright 1993 David Metcalfe
 * Copyright 1995, 1996 Alex Korobka
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */

#define NONAMELESSUNION
#define NONAMELESSSTRUCT

#include "config.h"
#include "wine/port.h"

#include <assert.h>
#include <fcntl.h>
#include <poll.h>
#include <errno.h>
#include <stdarg.h>
#include <stdlib.h>
#include <stdio.h>
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif

#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "winuser.h"
#include "wine/unicode.h"

#include "android.h"
#include "wine/server.h"
#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(android);

/* private window data */
struct android_win_data
{
    HWND           hwnd;           /* hwnd that this private data belongs to */
    HWND           parent;         /* parent hwnd for child windows */
    RECT           window_rect;    /* USER window rectangle relative to parent */
    RECT           whole_rect;     /* X window rectangle for the whole window relative to parent */
    RECT           client_rect;    /* client area relative to parent */
    ANativeWindow *window;         /* native window wrapper that forwards calls to the desktop process */
    struct window_surface *surface;
};

#define SWP_AGG_NOPOSCHANGE (SWP_NOSIZE | SWP_NOMOVE | SWP_NOCLIENTSIZE | SWP_NOCLIENTMOVE | SWP_NOZORDER)

static CRITICAL_SECTION win_data_section;
static CRITICAL_SECTION_DEBUG critsect_debug =
{
    0, 0, &win_data_section,
    { &critsect_debug.ProcessLocksList, &critsect_debug.ProcessLocksList },
      0, 0, { (DWORD_PTR)(__FILE__ ": win_data_section") }
};
static CRITICAL_SECTION win_data_section = { &critsect_debug, -1, 0, 0, 0, 0 };

static struct android_win_data *win_data_context[32768];

static inline int context_idx( HWND hwnd )
{
    return LOWORD( hwnd ) >> 1;
}

static void set_surface_region( struct window_surface *window_surface, HRGN win_region );

/* only for use on sanitized BITMAPINFO structures */
static inline int get_dib_info_size( const BITMAPINFO *info, UINT coloruse )
{
    if (info->bmiHeader.biCompression == BI_BITFIELDS)
        return sizeof(BITMAPINFOHEADER) + 3 * sizeof(DWORD);
    if (coloruse == DIB_PAL_COLORS)
        return sizeof(BITMAPINFOHEADER) + info->bmiHeader.biClrUsed * sizeof(WORD);
    return FIELD_OFFSET( BITMAPINFO, bmiColors[info->bmiHeader.biClrUsed] );
}

static inline int get_dib_stride( int width, int bpp )
{
    return ((width * bpp + 31) >> 3) & ~3;
}

static inline int get_dib_image_size( const BITMAPINFO *info )
{
    return get_dib_stride( info->bmiHeader.biWidth, info->bmiHeader.biBitCount )
        * abs( info->bmiHeader.biHeight );
}


/***********************************************************************
 *           alloc_win_data
 */
static struct android_win_data *alloc_win_data( HWND hwnd )
{
    struct android_win_data *data;

    if ((data = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*data))))
    {
        data->hwnd = hwnd;
        data->window = create_ioctl_window( hwnd, FALSE );
        EnterCriticalSection( &win_data_section );
        win_data_context[context_idx(hwnd)] = data;
    }
    return data;
}


/***********************************************************************
 *           free_win_data
 */
static void free_win_data( struct android_win_data *data )
{
    win_data_context[context_idx( data->hwnd )] = NULL;
    LeaveCriticalSection( &win_data_section );
    if (data->window) release_ioctl_window( data->window );
    HeapFree( GetProcessHeap(), 0, data );
}


/***********************************************************************
 *           get_win_data
 *
 * Lock and return the data structure associated with a window.
 */
static struct android_win_data *get_win_data( HWND hwnd )
{
    struct android_win_data *data;

    if (!hwnd) return NULL;
    EnterCriticalSection( &win_data_section );
    if ((data = win_data_context[context_idx(hwnd)]) && data->hwnd == hwnd) return data;
    LeaveCriticalSection( &win_data_section );
    return NULL;
}


/***********************************************************************
 *           release_win_data
 *
 * Release the data returned by get_win_data.
 */
static void release_win_data( struct android_win_data *data )
{
    if (data) LeaveCriticalSection( &win_data_section );
}


/***********************************************************************
 *           get_ioctl_window
 */
static struct ANativeWindow *get_ioctl_window( HWND hwnd )
{
    struct ANativeWindow *ret;
    struct android_win_data *data = get_win_data( hwnd );

    if (!data || !data->window) return NULL;
    ret = grab_ioctl_window( data->window );
    release_win_data( data );
    return ret;
}


/* Handling of events coming from the Java side */

struct java_event
{
    struct list      entry;
    union event_data data;
};

static struct list event_queue = LIST_INIT( event_queue );
static struct java_event *current_event;
static int event_pipe[2];
static DWORD desktop_tid;

/***********************************************************************
 *           send_event
 */
int send_event( const union event_data *data )
{
    int res;

    if ((res = write( event_pipe[1], data, sizeof(*data) )) != sizeof(*data))
    {
        p__android_log_print( ANDROID_LOG_ERROR, "wine", "failed to send event" );
        return -1;
    }
    return 0;
}


/***********************************************************************
 *           desktop_changed
 *
 * JNI callback, runs in the context of the Java thread.
 */
void desktop_changed( JNIEnv *env, jobject obj, jint width, jint height )
{
    union event_data data;

    memset( &data, 0, sizeof(data) );
    data.type = DESKTOP_CHANGED;
    data.desktop.width = width;
    data.desktop.height = height;
    p__android_log_print( ANDROID_LOG_INFO, "wine", "desktop_changed: %ux%u", width, height );
    send_event( &data );
}


/***********************************************************************
 *           config_changed
 *
 * JNI callback, runs in the context of the Java thread.
 */
void config_changed( JNIEnv *env, jobject obj, jint dpi )
{
    union event_data data;

    memset( &data, 0, sizeof(data) );
    data.type = CONFIG_CHANGED;
    data.cfg.dpi = dpi;
    p__android_log_print( ANDROID_LOG_INFO, "wine", "config_changed: %u dpi", dpi );
    send_event( &data );
}


/***********************************************************************
 *           surface_changed
 *
 * JNI callback, runs in the context of the Java thread.
 */
void surface_changed( JNIEnv *env, jobject obj, jint win, jobject surface, jboolean client )
{
    union event_data data;

    memset( &data, 0, sizeof(data) );
    data.surface.hwnd = LongToHandle( win );
    data.surface.client = client;
    if (surface)
    {
        int width, height;
        ANativeWindow *win = pANativeWindow_fromSurface( env, surface );

        if (win->query( win, NATIVE_WINDOW_WIDTH, &width ) < 0) width = 0;
        if (win->query( win, NATIVE_WINDOW_HEIGHT, &height ) < 0) height = 0;
        data.surface.window = win;
        data.surface.width = width;
        data.surface.height = height;
        p__android_log_print( ANDROID_LOG_INFO, "wine", "surface_changed: %p %s %ux%u",
                              data.surface.hwnd, client ? "client" : "whole", width, height );
    }
    data.type = SURFACE_CHANGED;
    send_event( &data );
}


/***********************************************************************
 *           motion_event
 *
 * JNI callback, runs in the context of the Java thread.
 */
jboolean motion_event( JNIEnv *env, jobject obj, jint win, jint action, jint x, jint y, jint state, jint vscroll )
{
    static LONG button_state;
    union event_data data;
    int prev_state;

    int mask = action & AMOTION_EVENT_ACTION_MASK;

    if (!( mask == AMOTION_EVENT_ACTION_DOWN ||
           mask == AMOTION_EVENT_ACTION_UP ||
           mask == AMOTION_EVENT_ACTION_SCROLL ||
           mask == AMOTION_EVENT_ACTION_MOVE ||
           mask == AMOTION_EVENT_ACTION_HOVER_MOVE ))
        return JNI_FALSE;

    prev_state = InterlockedExchange( &button_state, state );

    data.type = MOTION_EVENT;
    data.motion.hwnd = LongToHandle( win );
    data.motion.input.type             = INPUT_MOUSE;
    data.motion.input.u.mi.dx          = x;
    data.motion.input.u.mi.dy          = y;
    data.motion.input.u.mi.mouseData   = 0;
    data.motion.input.u.mi.time        = 0;
    data.motion.input.u.mi.dwExtraInfo = 0;
    data.motion.input.u.mi.dwFlags     = MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE;
    switch (action & AMOTION_EVENT_ACTION_MASK)
    {
    case AMOTION_EVENT_ACTION_DOWN:
        if ((state & ~prev_state) & AMOTION_EVENT_BUTTON_PRIMARY)
            data.motion.input.u.mi.dwFlags |= MOUSEEVENTF_LEFTDOWN;
        if ((state & ~prev_state) & AMOTION_EVENT_BUTTON_SECONDARY)
            data.motion.input.u.mi.dwFlags |= MOUSEEVENTF_RIGHTDOWN;
        if ((state & ~prev_state) & AMOTION_EVENT_BUTTON_TERTIARY)
            data.motion.input.u.mi.dwFlags |= MOUSEEVENTF_MIDDLEDOWN;
        if (!(state & ~prev_state)) /* touch event */
            data.motion.input.u.mi.dwFlags |= MOUSEEVENTF_LEFTDOWN;
        break;
    case AMOTION_EVENT_ACTION_UP:
        if ((prev_state & ~state) & AMOTION_EVENT_BUTTON_PRIMARY)
            data.motion.input.u.mi.dwFlags |= MOUSEEVENTF_LEFTUP;
        if ((prev_state & ~state) & AMOTION_EVENT_BUTTON_SECONDARY)
            data.motion.input.u.mi.dwFlags |= MOUSEEVENTF_RIGHTUP;
        if ((prev_state & ~state) & AMOTION_EVENT_BUTTON_TERTIARY)
            data.motion.input.u.mi.dwFlags |= MOUSEEVENTF_MIDDLEUP;
        if (!(prev_state & ~state)) /* touch event */
            data.motion.input.u.mi.dwFlags |= MOUSEEVENTF_LEFTUP;
        break;
    case AMOTION_EVENT_ACTION_SCROLL:
        data.motion.input.u.mi.dwFlags |= MOUSEEVENTF_WHEEL;
        data.motion.input.u.mi.mouseData = vscroll < 0 ? -WHEEL_DELTA : WHEEL_DELTA;
        break;
    case AMOTION_EVENT_ACTION_MOVE:
    case AMOTION_EVENT_ACTION_HOVER_MOVE:
        break;
    default:
        return JNI_FALSE;
    }
    send_event( &data );
    return JNI_TRUE;
}


/***********************************************************************
 *           init_event_queue
 */
static void init_event_queue(void)
{
    HANDLE handle;
    int ret;

    if (pipe2( event_pipe, O_CLOEXEC | O_NONBLOCK ) == -1)
    {
        ERR( "could not create data\n" );
        ExitProcess(1);
    }
    if (wine_server_fd_to_handle( event_pipe[0], GENERIC_READ | SYNCHRONIZE, 0, &handle ))
    {
        ERR( "Can't allocate handle for event fd\n" );
        ExitProcess(1);
    }
    SERVER_START_REQ( set_queue_fd )
    {
        req->handle = wine_server_obj_handle( handle );
        ret = wine_server_call( req );
    }
    SERVER_END_REQ;
    if (ret)
    {
        ERR( "Can't store handle for event fd %x\n", ret );
        ExitProcess(1);
    }
    CloseHandle( handle );
    desktop_tid = GetCurrentThreadId();
}


/***********************************************************************
 *           pull_events
 *
 * Pull events from the event pipe and add them to the queue
 */
static void pull_events(void)
{
    struct java_event *event;
    int res;

    for (;;)
    {
        if (!(event = HeapAlloc( GetProcessHeap(), 0, sizeof(*event) ))) break;

        res = read( event_pipe[0], &event->data, sizeof(event->data) );
        if (res != sizeof(event->data)) break;
        list_add_tail( &event_queue, &event->entry );
    }
    HeapFree( GetProcessHeap(), 0, event );
}


/***********************************************************************
 *           process_events
 */
static int process_events( DWORD mask )
{
    struct java_event *event, *next, *previous;
    unsigned int count = 0;

    assert( GetCurrentThreadId() == desktop_tid );

    pull_events();

    previous = current_event;

    LIST_FOR_EACH_ENTRY_SAFE( event, next, &event_queue, struct java_event, entry )
    {
        switch (event->data.type)
        {
        case SURFACE_CHANGED:
            break;  /* always process it to unblock other threads */
        case MOTION_EVENT:
            if (event->data.motion.input.u.mi.dwFlags & (MOUSEEVENTF_LEFTDOWN|MOUSEEVENTF_RIGHTDOWN|
                                                         MOUSEEVENTF_MIDDLEDOWN|MOUSEEVENTF_LEFTUP|
                                                         MOUSEEVENTF_RIGHTUP|MOUSEEVENTF_MIDDLEUP))
            {
                if (mask & QS_MOUSEBUTTON) break;
            }
            else if (mask & QS_MOUSEMOVE) break;
            continue;  /* skip it */
        case KEYBOARD_EVENT:
            if (mask & QS_KEY) break;
            continue;  /* skip it */
        default:
            if (mask & QS_SENDMESSAGE) break;
            continue;  /* skip it */
        }

        /* remove it first, in case we process events recursively */
        list_remove( &event->entry );
        current_event = event;

        switch (event->data.type)
        {
        case DESKTOP_CHANGED:
            TRACE( "DESKTOP_CHANGED %ux%u\n", event->data.desktop.width, event->data.desktop.height );
            screen_width = event->data.desktop.width;
            screen_height = event->data.desktop.height;
            init_monitors( screen_width, screen_height );
            SetWindowPos( GetDesktopWindow(), 0, 0, 0, screen_width, screen_height,
                          SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOREDRAW );
            break;

        case CONFIG_CHANGED:
            TRACE( "CONFIG_CHANGED dpi %u\n", event->data.cfg.dpi );
            set_screen_dpi( event->data.cfg.dpi );
            break;

        case SURFACE_CHANGED:
            TRACE("SURFACE_CHANGED %p %p %s size %ux%u\n", event->data.surface.hwnd,
                  event->data.surface.window, event->data.surface.client ? "client" : "whole",
                  event->data.surface.width, event->data.surface.height );

            register_native_window( event->data.surface.hwnd, event->data.surface.window, event->data.surface.client );
            break;

        case MOTION_EVENT:
            {
                HWND capture = get_capture_window();

                if (event->data.motion.input.u.mi.dwFlags & (MOUSEEVENTF_LEFTDOWN|MOUSEEVENTF_RIGHTDOWN|MOUSEEVENTF_MIDDLEDOWN))
                    TRACE( "BUTTONDOWN pos %d,%d hwnd %p flags %x\n",
                           event->data.motion.input.u.mi.dx, event->data.motion.input.u.mi.dy,
                           event->data.motion.hwnd, event->data.motion.input.u.mi.dwFlags );
                else if (event->data.motion.input.u.mi.dwFlags & (MOUSEEVENTF_LEFTUP|MOUSEEVENTF_RIGHTUP|MOUSEEVENTF_MIDDLEUP))
                    TRACE( "BUTTONUP pos %d,%d hwnd %p flags %x\n",
                           event->data.motion.input.u.mi.dx, event->data.motion.input.u.mi.dy,
                           event->data.motion.hwnd, event->data.motion.input.u.mi.dwFlags );
                else
                    TRACE( "MOUSEMOVE pos %d,%d hwnd %p flags %x\n",
                           event->data.motion.input.u.mi.dx, event->data.motion.input.u.mi.dy,
                           event->data.motion.hwnd, event->data.motion.input.u.mi.dwFlags );
                if (!capture && (event->data.motion.input.u.mi.dwFlags & MOUSEEVENTF_ABSOLUTE))
                {
                    RECT rect;
                    SetRect( &rect, event->data.motion.input.u.mi.dx, event->data.motion.input.u.mi.dy,
                             event->data.motion.input.u.mi.dx + 1, event->data.motion.input.u.mi.dy + 1 );
                    MapWindowPoints( 0, event->data.motion.hwnd, (POINT *)&rect, 2 );

                    SERVER_START_REQ( update_window_zorder )
                    {
                        req->window      = wine_server_user_handle( event->data.motion.hwnd );
                        req->rect.left   = rect.left;
                        req->rect.top    = rect.top;
                        req->rect.right  = rect.right;
                        req->rect.bottom = rect.bottom;
                        wine_server_call( req );
                    }
                    SERVER_END_REQ;
                }
                __wine_send_input( capture ? capture : event->data.motion.hwnd, &event->data.motion.input );
            }
            break;

        case KEYBOARD_EVENT:
            if (event->data.kbd.input.u.ki.dwFlags & KEYEVENTF_KEYUP)
                TRACE("KEYUP hwnd %p vkey %x '%c' scancode %x\n", event->data.kbd.hwnd,
                      event->data.kbd.input.u.ki.wVk, event->data.kbd.input.u.ki.wVk,
                      event->data.kbd.input.u.ki.wScan );
            else
                TRACE("KEYDOWN hwnd %p vkey %x '%c' scancode %x\n", event->data.kbd.hwnd,
                      event->data.kbd.input.u.ki.wVk, event->data.kbd.input.u.ki.wVk,
                      event->data.kbd.input.u.ki.wScan );
            update_keyboard_lock_state( event->data.kbd.input.u.ki.wVk, event->data.kbd.lock_state );
            __wine_send_input( 0, &event->data.kbd.input );
            break;

        default:
            FIXME( "got event %u\n", event->data.type );
        }
        HeapFree( GetProcessHeap(), 0, event );
        count++;
        /* next may have been removed by a recursive call, so reset it to the beginning of the list */
        next = LIST_ENTRY( event_queue.next, struct java_event, entry );
    }
    current_event = previous;
    return count;
}


/***********************************************************************
 *           wait_events
 */
static int wait_events( int timeout )
{
    assert( GetCurrentThreadId() == desktop_tid );

    for (;;)
    {
        struct pollfd pollfd;
        int ret;

        pollfd.fd = event_pipe[0];
        pollfd.events = POLLIN | POLLHUP;
        ret = poll( &pollfd, 1, timeout );
        if (ret == -1 && errno == EINTR) continue;
        if (ret && (pollfd.revents & (POLLHUP | POLLERR))) ret = -1;
        return ret;
    }
}


/* Window surface support */

struct android_window_surface
{
    struct window_surface header;
    HWND                  hwnd;
    ANativeWindow        *window;
    RECT                  bounds;
    BOOL                  byteswap;
    RGNDATA              *region_data;
    HRGN                  region;
    BYTE                  alpha;
    COLORREF              color_key;
    void                 *bits;
    CRITICAL_SECTION      crit;
    BITMAPINFO            info;   /* variable size, must be last */
};

static struct android_window_surface *get_android_surface( struct window_surface *surface )
{
    return (struct android_window_surface *)surface;
}

static inline void reset_bounds( RECT *bounds )
{
    bounds->left = bounds->top = INT_MAX;
    bounds->right = bounds->bottom = INT_MIN;
}

static inline void add_bounds_rect( RECT *bounds, const RECT *rect )
{
    if (rect->left >= rect->right || rect->top >= rect->bottom) return;
    bounds->left   = min( bounds->left, rect->left );
    bounds->top    = min( bounds->top, rect->top );
    bounds->right  = max( bounds->right, rect->right );
    bounds->bottom = max( bounds->bottom, rect->bottom );
}

/* store the palette or color mask data in the bitmap info structure */
static void set_color_info( BITMAPINFO *info, BOOL has_alpha )
{
    DWORD *colors = (DWORD *)info->bmiColors;

    info->bmiHeader.biSize = sizeof(info->bmiHeader);
    info->bmiHeader.biClrUsed = 0;
    info->bmiHeader.biBitCount = 32;
    if (has_alpha)
    {
        info->bmiHeader.biCompression = BI_RGB;
        return;
    }
    info->bmiHeader.biCompression = BI_BITFIELDS;
    colors[0] = 0xff0000;
    colors[1] = 0x00ff00;
    colors[2] = 0x0000ff;
}

/* apply the window region to a single line of the destination image. */
static void apply_line_region( DWORD *dst, int width, int x, int y, const RECT *rect, const RECT *end )
{
    while (rect < end && rect->top <= y && width > 0)
    {
        if (rect->left > x)
        {
            memset( dst, 0, min( rect->left - x, width ) * sizeof(*dst) );
            dst += rect->left - x;
            width -= rect->left - x;
            x = rect->left;
        }
        if (rect->right > x)
        {
            dst += rect->right - x;
            width -= rect->right - x;
            x = rect->right;
        }
        rect++;
    }
    if (width > 0) memset( dst, 0, width * sizeof(*dst) );
}

/***********************************************************************
 *           android_surface_lock
 */
static void android_surface_lock( struct window_surface *window_surface )
{
    struct android_window_surface *surface = get_android_surface( window_surface );

    EnterCriticalSection( &surface->crit );
}

/***********************************************************************
 *           android_surface_unlock
 */
static void android_surface_unlock( struct window_surface *window_surface )
{
    struct android_window_surface *surface = get_android_surface( window_surface );

    LeaveCriticalSection( &surface->crit );
}

/***********************************************************************
 *           android_surface_get_bitmap_info
 */
static void *android_surface_get_bitmap_info( struct window_surface *window_surface, BITMAPINFO *info )
{
    struct android_window_surface *surface = get_android_surface( window_surface );

    memcpy( info, &surface->info, get_dib_info_size( &surface->info, DIB_RGB_COLORS ));
    return surface->bits;
}

/***********************************************************************
 *           android_surface_get_bounds
 */
static RECT *android_surface_get_bounds( struct window_surface *window_surface )
{
    struct android_window_surface *surface = get_android_surface( window_surface );

    return &surface->bounds;
}

/***********************************************************************
 *           android_surface_set_region
 */
static void android_surface_set_region( struct window_surface *window_surface, HRGN region )
{
    struct android_window_surface *surface = get_android_surface( window_surface );

    TRACE( "updating surface %p hwnd %p with %p\n", surface, surface->hwnd, region );

    window_surface->funcs->lock( window_surface );
    if (!region)
    {
        if (surface->region) DeleteObject( surface->region );
        surface->region = 0;
    }
    else
    {
        if (!surface->region) surface->region = CreateRectRgn( 0, 0, 0, 0 );
        CombineRgn( surface->region, region, 0, RGN_COPY );
    }
    window_surface->funcs->unlock( window_surface );
    set_surface_region( &surface->header, (HRGN)1 );
}

/***********************************************************************
 *           android_surface_flush
 */
static void android_surface_flush( struct window_surface *window_surface )
{
    struct android_window_surface *surface = get_android_surface( window_surface );
    ANativeWindow_Buffer buffer;
    ARect rc;
    RECT rect;
    BOOL needs_flush;

    window_surface->funcs->lock( window_surface );
    SetRect( &rect, 0, 0, surface->header.rect.right - surface->header.rect.left,
             surface->header.rect.bottom - surface->header.rect.top );
    needs_flush = IntersectRect( &rect, &rect, &surface->bounds );
    reset_bounds( &surface->bounds );
    window_surface->funcs->unlock( window_surface );
    if (!needs_flush) return;

    TRACE( "flushing %p hwnd %p surface %s rect %s bits %p alpha %02x key %08x region %u rects\n",
           surface, surface->hwnd, wine_dbgstr_rect( &surface->header.rect ),
           wine_dbgstr_rect( &rect ), surface->bits, surface->alpha, surface->color_key,
           surface->region_data ? surface->region_data->rdh.nCount : 0 );

    rc.left   = rect.left;
    rc.top    = rect.top;
    rc.right  = rect.right;
    rc.bottom = rect.bottom;

    if (!surface->window->perform( surface->window, NATIVE_WINDOW_LOCK, &buffer, &rc ))
    {
        const RECT *rgn_rect = NULL, *end = NULL;
        unsigned int *src, *dst;
        int x, y, width;

        rect.left   = rc.left;
        rect.top    = rc.top;
        rect.right  = rc.right;
        rect.bottom = rc.bottom;
        IntersectRect( &rect, &rect, &surface->header.rect );

        if (surface->region_data)
        {
            rgn_rect = (RECT *)surface->region_data->Buffer;
            end = rgn_rect + surface->region_data->rdh.nCount;
        }
        src = (unsigned int *)surface->bits
            + (rect.top - surface->header.rect.top) * surface->info.bmiHeader.biWidth
            + (rect.left - surface->header.rect.left);
        dst = (unsigned int *)buffer.bits + rect.top * buffer.stride + rect.left;
        width = min( rect.right - rect.left, buffer.stride );

        for (y = rect.top; y < min( buffer.height, rect.bottom); y++)
        {
            if (surface->info.bmiHeader.biCompression == BI_RGB)
                memcpy( dst, src, width * sizeof(*dst) );
            else if (surface->alpha == 255)
                for (x = 0; x < width; x++) dst[x] = src[x] | 0xff000000;
            else
                for (x = 0; x < width; x++)
                    dst[x] = ((surface->alpha << 24) |
                              (((BYTE)(src[x] >> 16) * surface->alpha / 255) << 16) |
                              (((BYTE)(src[x] >> 8) * surface->alpha / 255) << 8) |
                              (((BYTE)src[x] * surface->alpha / 255)));

            if (surface->color_key != CLR_INVALID)
                for (x = 0; x < width; x++) if ((src[x] & 0xffffff) == surface->color_key) dst[x] = 0;

            if (rgn_rect)
            {
                while (rgn_rect < end && rgn_rect->bottom <= y) rgn_rect++;
                apply_line_region( dst, width, rect.left, y, rgn_rect, end );
            }

            src += surface->info.bmiHeader.biWidth;
            dst += buffer.stride;
        }
        surface->window->perform( surface->window, NATIVE_WINDOW_UNLOCK_AND_POST );
    }
    else TRACE( "Unable to lock surface %p window %p buffer %p\n",
                surface, surface->hwnd, surface->window );
}

/***********************************************************************
 *           android_surface_destroy
 */
static void android_surface_destroy( struct window_surface *window_surface )
{
    struct android_window_surface *surface = get_android_surface( window_surface );

    TRACE( "freeing %p bits %p\n", surface, surface->bits );

    surface->crit.DebugInfo->Spare[0] = 0;
    DeleteCriticalSection( &surface->crit );
    HeapFree( GetProcessHeap(), 0, surface->region_data );
    if (surface->region) DeleteObject( surface->region );
    release_ioctl_window( surface->window );
    HeapFree( GetProcessHeap(), 0, surface->bits );
    HeapFree( GetProcessHeap(), 0, surface );
}

static const struct window_surface_funcs android_surface_funcs =
{
    android_surface_lock,
    android_surface_unlock,
    android_surface_get_bitmap_info,
    android_surface_get_bounds,
    android_surface_set_region,
    android_surface_flush,
    android_surface_destroy
};

static BOOL is_argb_surface( struct window_surface *surface )
{
    return surface && surface->funcs == &android_surface_funcs &&
        get_android_surface( surface )->info.bmiHeader.biCompression == BI_RGB;
}

/***********************************************************************
 *           set_color_key
 */
static void set_color_key( struct android_window_surface *surface, COLORREF key )
{
    if (key == CLR_INVALID)
        surface->color_key = CLR_INVALID;
    else if (surface->info.bmiHeader.biBitCount <= 8)
        surface->color_key = CLR_INVALID;
    else if (key & (1 << 24))  /* PALETTEINDEX */
        surface->color_key = 0;
    else if (key >> 16 == 0x10ff)  /* DIBINDEX */
        surface->color_key = 0;
    else if (surface->info.bmiHeader.biBitCount == 24)
        surface->color_key = key;
    else
        surface->color_key = (GetRValue(key) << 16) | (GetGValue(key) << 8) | GetBValue(key);
}

/***********************************************************************
 *           set_surface_region
 */
static void set_surface_region( struct window_surface *window_surface, HRGN win_region )
{
    struct android_window_surface *surface = get_android_surface( window_surface );
    struct android_win_data *win_data;
    HRGN region = win_region;
    RGNDATA *data = NULL;
    DWORD size;
    int offset_x, offset_y;

    if (window_surface->funcs != &android_surface_funcs) return;  /* we may get the null surface */

    if (!(win_data = get_win_data( surface->hwnd ))) return;
    offset_x = win_data->window_rect.left - win_data->whole_rect.left;
    offset_y = win_data->window_rect.top - win_data->whole_rect.top;
    release_win_data( win_data );

    if (win_region == (HRGN)1)  /* hack: win_region == 1 means retrieve region from server */
    {
        region = CreateRectRgn( 0, 0, win_data->window_rect.right - win_data->window_rect.left,
                                win_data->window_rect.bottom - win_data->window_rect.top );
        if (GetWindowRgn( surface->hwnd, region ) == ERROR && !surface->region) goto done;
    }

    OffsetRgn( region, offset_x, offset_y );
    if (surface->region) CombineRgn( region, region, surface->region, RGN_AND );

    if (!(size = GetRegionData( region, 0, NULL ))) goto done;
    if (!(data = HeapAlloc( GetProcessHeap(), 0, size ))) goto done;

    if (!GetRegionData( region, size, data ))
    {
        HeapFree( GetProcessHeap(), 0, data );
        data = NULL;
    }

done:
    window_surface->funcs->lock( window_surface );
    HeapFree( GetProcessHeap(), 0, surface->region_data );
    surface->region_data = data;
    *window_surface->funcs->get_bounds( window_surface ) = surface->header.rect;
    window_surface->funcs->unlock( window_surface );
    if (region != win_region) DeleteObject( region );
}

/***********************************************************************
 *           create_surface
 */
static struct window_surface *create_surface( HWND hwnd, const RECT *rect,
                                              BYTE alpha, COLORREF color_key, BOOL src_alpha )
{
    struct android_window_surface *surface;
    int width = rect->right - rect->left, height = rect->bottom - rect->top;

    surface = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
                         FIELD_OFFSET( struct android_window_surface, info.bmiColors[3] ));
    if (!surface) return NULL;
    set_color_info( &surface->info, src_alpha );
    surface->info.bmiHeader.biWidth       = width;
    surface->info.bmiHeader.biHeight      = -height; /* top-down */
    surface->info.bmiHeader.biPlanes      = 1;
    surface->info.bmiHeader.biSizeImage   = get_dib_image_size( &surface->info );

    InitializeCriticalSection( &surface->crit );
    surface->crit.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": surface");

    surface->header.funcs = &android_surface_funcs;
    surface->header.rect  = *rect;
    surface->header.ref   = 1;
    surface->hwnd         = hwnd;
    surface->window       = get_ioctl_window( hwnd );
    surface->alpha        = alpha;
    set_color_key( surface, color_key );
    set_surface_region( &surface->header, (HRGN)1 );
    reset_bounds( &surface->bounds );

    if (!(surface->bits = HeapAlloc( GetProcessHeap(), 0, surface->info.bmiHeader.biSizeImage )))
        goto failed;

    TRACE( "created %p hwnd %p %s bits %p-%p\n", surface, hwnd, wine_dbgstr_rect(rect),
           surface->bits, (char *)surface->bits + surface->info.bmiHeader.biSizeImage );

    return &surface->header;

failed:
    android_surface_destroy( &surface->header );
    return NULL;
}

/***********************************************************************
 *           set_surface_layered
 */
static void set_surface_layered( struct window_surface *window_surface, BYTE alpha, COLORREF color_key )
{
    struct android_window_surface *surface = get_android_surface( window_surface );
    COLORREF prev_key;
    BYTE prev_alpha;

    if (window_surface->funcs != &android_surface_funcs) return;  /* we may get the null surface */

    window_surface->funcs->lock( window_surface );
    prev_key = surface->color_key;
    prev_alpha = surface->alpha;
    surface->alpha = alpha;
    set_color_key( surface, color_key );
    if (alpha != prev_alpha || surface->color_key != prev_key)  /* refresh */
        *window_surface->funcs->get_bounds( window_surface ) = surface->header.rect;
    window_surface->funcs->unlock( window_surface );
}


static WNDPROC desktop_orig_wndproc;

static LRESULT CALLBACK desktop_wndproc_wrapper( HWND hwnd, UINT msg, WPARAM wp, LPARAM lp )
{
    switch (msg)
    {
    case WM_PARENTNOTIFY:
        if (LOWORD(wp) == WM_DESTROY) destroy_ioctl_window( (HWND)lp, FALSE );
        break;
    }
    return desktop_orig_wndproc( hwnd, msg, wp, lp );
}


/***********************************************************************
 *           ANDROID_MsgWaitForMultipleObjectsEx
 */
DWORD CDECL ANDROID_MsgWaitForMultipleObjectsEx( DWORD count, const HANDLE *handles,
                                                 DWORD timeout, DWORD mask, DWORD flags )
{
    if (GetCurrentThreadId() == desktop_tid)
    {
        /* don't process nested events */
        if (current_event) mask = 0;
        if (process_events( mask )) return count - 1;
    }
    return WaitForMultipleObjectsEx( count, handles, flags & MWMO_WAITALL,
                                     timeout, flags & MWMO_ALERTABLE );
}

/**********************************************************************
 *           ANDROID_CreateWindow
 */
BOOL CDECL ANDROID_CreateWindow( HWND hwnd )
{
    TRACE( "%p\n", hwnd );

    if (hwnd == GetDesktopWindow())
    {
        struct android_win_data *data;

        init_event_queue();
        start_android_device();
        if (!(data = alloc_win_data( hwnd ))) return FALSE;
        release_win_data( data );
    }
    return TRUE;
}


/***********************************************************************
 *           ANDROID_DestroyWindow
 */
void CDECL ANDROID_DestroyWindow( HWND hwnd )
{
    struct android_win_data *data;

    if (!(data = get_win_data( hwnd ))) return;

    if (data->surface) window_surface_release( data->surface );
    data->surface = NULL;
    destroy_gl_drawable( hwnd );
    free_win_data( data );
}


/***********************************************************************
 *           create_win_data
 *
 * Create a data window structure for an existing window.
 */
static struct android_win_data *create_win_data( HWND hwnd, const RECT *window_rect,
                                                 const RECT *client_rect )
{
    struct android_win_data *data;
    HWND parent;

    if (!(parent = GetAncestor( hwnd, GA_PARENT ))) return NULL;  /* desktop or HWND_MESSAGE */

    if (!(data = alloc_win_data( hwnd ))) return NULL;

    data->parent = (parent == GetDesktopWindow()) ? 0 : parent;
    data->whole_rect = data->window_rect = *window_rect;
    data->client_rect = *client_rect;
    return data;
}


static inline RECT get_surface_rect( const RECT *visible_rect )
{
    RECT rect;

    IntersectRect( &rect, visible_rect, &virtual_screen_rect );
    OffsetRect( &rect, -visible_rect->left, -visible_rect->top );
    rect.left &= ~31;
    rect.top  &= ~31;
    rect.right  = max( rect.left + 32, (rect.right + 31) & ~31 );
    rect.bottom = max( rect.top + 32, (rect.bottom + 31) & ~31 );
    return rect;
}


/***********************************************************************
 *           ANDROID_WindowPosChanging
 */
void CDECL ANDROID_WindowPosChanging( HWND hwnd, HWND insert_after, UINT swp_flags,
                                     const RECT *window_rect, const RECT *client_rect, RECT *visible_rect,
                                     struct window_surface **surface )
{
    struct android_win_data *data = get_win_data( hwnd );
    RECT surface_rect;
    DWORD flags;
    COLORREF key;
    BYTE alpha;
    BOOL layered = GetWindowLongW( hwnd, GWL_EXSTYLE ) & WS_EX_LAYERED;

    TRACE( "win %p window %s client %s style %08x flags %08x\n",
           hwnd, wine_dbgstr_rect(window_rect), wine_dbgstr_rect(client_rect),
           GetWindowLongW( hwnd, GWL_STYLE ), swp_flags );

    if (!data && !(data = create_win_data( hwnd, window_rect, client_rect ))) return;

    *visible_rect = *window_rect;

    /* create the window surface if necessary */

    if (data->parent) goto done;
    if (swp_flags & SWP_HIDEWINDOW) goto done;
    if (is_argb_surface( data->surface )) goto done;

    surface_rect = get_surface_rect( visible_rect );
    if (data->surface)
    {
        if (!memcmp( &data->surface->rect, &surface_rect, sizeof(surface_rect) ))
        {
            /* existing surface is good enough */
            window_surface_add_ref( data->surface );
            if (*surface) window_surface_release( *surface );
            *surface = data->surface;
            goto done;
        }
    }
    if (!(swp_flags & SWP_SHOWWINDOW) && !(GetWindowLongW( hwnd, GWL_STYLE ) & WS_VISIBLE)) goto done;

    if (!layered || !GetLayeredWindowAttributes( hwnd, &key, &alpha, &flags )) flags = 0;
    if (!(flags & LWA_ALPHA)) alpha = 255;
    if (!(flags & LWA_COLORKEY)) key = CLR_INVALID;

    if (*surface) window_surface_release( *surface );
    *surface = create_surface( data->hwnd, &surface_rect, alpha, key, FALSE );

done:
    release_win_data( data );
}


/***********************************************************************
 *           ANDROID_WindowPosChanged
 */
void CDECL ANDROID_WindowPosChanged( HWND hwnd, HWND insert_after, UINT swp_flags,
                                    const RECT *window_rect, const RECT *client_rect,
                                    const RECT *visible_rect, const RECT *valid_rects,
                                    struct window_surface *surface )
{
    struct android_win_data *data;
    DWORD new_style = GetWindowLongW( hwnd, GWL_STYLE );
    HWND owner = 0;

    if (!(data = get_win_data( hwnd ))) return;

    data->window_rect = *window_rect;
    data->whole_rect  = *visible_rect;
    data->client_rect = *client_rect;

    if (!is_argb_surface( data->surface ))
    {
        if (surface) window_surface_add_ref( surface );
        if (data->surface) window_surface_release( data->surface );
        data->surface = surface;
    }
    if (!data->parent) owner = GetWindow( hwnd, GW_OWNER );
    release_win_data( data );

    if (!(swp_flags & SWP_NOZORDER)) insert_after = GetWindow( hwnd, GW_HWNDPREV );

    TRACE( "win %p window %s client %s style %08x owner %p after %p flags %08x\n", hwnd,
           wine_dbgstr_rect(window_rect), wine_dbgstr_rect(client_rect),
           new_style, owner, insert_after, swp_flags );

    ioctl_window_pos_changed( hwnd, window_rect, client_rect, visible_rect,
                              new_style, swp_flags, insert_after, owner );
}


/***********************************************************************
 *           ANDROID_ShowWindow
 */
UINT CDECL ANDROID_ShowWindow( HWND hwnd, INT cmd, RECT *rect, UINT swp )
{
    if (IsRectEmpty( rect )) return swp;
    if (!IsIconic( hwnd )) return swp;
    /* always hide icons off-screen */
    if (rect->left != -32000 || rect->top != -32000)
    {
        OffsetRect( rect, -32000 - rect->left, -32000 - rect->top );
        swp &= ~(SWP_NOMOVE | SWP_NOCLIENTMOVE);
    }
    return swp;
}


/*****************************************************************
 *	     ANDROID_SetParent
 */
void CDECL ANDROID_SetParent( HWND hwnd, HWND parent, HWND old_parent )
{
    struct android_win_data *data;

    if (parent == old_parent) return;
    if (!(data = get_win_data( hwnd ))) return;

    TRACE( "win %p parent %p -> %p\n", hwnd, old_parent, parent );

    data->parent = (parent == GetDesktopWindow()) ? 0 : parent;
    ioctl_set_window_parent( hwnd, parent );
    release_win_data( data );
}


/***********************************************************************
 *           ANDROID_SetCapture
 */
void CDECL ANDROID_SetCapture( HWND hwnd, UINT flags )
{
    if (!(flags & (GUI_INMOVESIZE | GUI_INMENUMODE))) return;
    ioctl_set_capture( hwnd );
}


/***********************************************************************
 *           ANDROID_SetWindowStyle
 */
void CDECL ANDROID_SetWindowStyle( HWND hwnd, INT offset, STYLESTRUCT *style )
{
    struct android_win_data *data;
    DWORD changed = style->styleNew ^ style->styleOld;

    if (hwnd == GetDesktopWindow()) return;
    if (!(data = get_win_data( hwnd ))) return;

    if (offset == GWL_EXSTYLE && (changed & WS_EX_LAYERED)) /* changing WS_EX_LAYERED resets attributes */
    {
        if (is_argb_surface( data->surface ))
        {
            if (data->surface) window_surface_release( data->surface );
            data->surface = NULL;
        }
        else if (data->surface) set_surface_layered( data->surface, 255, CLR_INVALID );
    }
    release_win_data( data );
}


/***********************************************************************
 *           ANDROID_SetWindowRgn
 */
void CDECL ANDROID_SetWindowRgn( HWND hwnd, HRGN hrgn, BOOL redraw )
{
    struct android_win_data *data;

    if ((data = get_win_data( hwnd )))
    {
        if (data->surface) set_surface_region( data->surface, hrgn );
        release_win_data( data );
    }
    else FIXME( "not supported on other process window %p\n", hwnd );
}


/***********************************************************************
 *	     ANDROID_SetLayeredWindowAttributes
 */
void CDECL ANDROID_SetLayeredWindowAttributes( HWND hwnd, COLORREF key, BYTE alpha, DWORD flags )
{
    struct android_win_data *data;

    if (!(flags & LWA_ALPHA)) alpha = 255;
    if (!(flags & LWA_COLORKEY)) key = CLR_INVALID;

    if ((data = get_win_data( hwnd )))
    {
        if (data->surface) set_surface_layered( data->surface, alpha, key );
        release_win_data( data );
    }
}


/*****************************************************************************
 *           ANDROID_UpdateLayeredWindow
 */
BOOL CDECL ANDROID_UpdateLayeredWindow( HWND hwnd, const UPDATELAYEREDWINDOWINFO *info,
                                        const RECT *window_rect )
{
    struct window_surface *surface;
    struct android_win_data *data;
    BLENDFUNCTION blend = { AC_SRC_OVER, 0, 255, 0 };
    COLORREF color_key = (info->dwFlags & ULW_COLORKEY) ? info->crKey : CLR_INVALID;
    char buffer[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )];
    BITMAPINFO *bmi = (BITMAPINFO *)buffer;
    void *src_bits, *dst_bits;
    RECT rect, src_rect;
    HDC hdc = 0;
    HBITMAP dib;
    BOOL ret = FALSE;

    if (!(data = get_win_data( hwnd ))) return FALSE;

    rect = *window_rect;
    OffsetRect( &rect, -window_rect->left, -window_rect->top );

    surface = data->surface;
    if (!is_argb_surface( surface ))
    {
        if (surface) window_surface_release( surface );
        surface = NULL;
    }

    if (!surface || !EqualRect( &surface->rect, &rect ))
    {
        data->surface = create_surface( data->hwnd, &rect, 255, color_key, TRUE );
        if (surface) window_surface_release( surface );
        surface = data->surface;
    }
    else set_surface_layered( surface, 255, color_key );

    if (surface) window_surface_add_ref( surface );
    release_win_data( data );

    if (!surface) return FALSE;
    if (!info->hdcSrc)
    {
        window_surface_release( surface );
        return TRUE;
    }

    dst_bits = surface->funcs->get_info( surface, bmi );

    if (!(dib = CreateDIBSection( info->hdcDst, bmi, DIB_RGB_COLORS, &src_bits, NULL, 0 ))) goto done;
    if (!(hdc = CreateCompatibleDC( 0 ))) goto done;

    SelectObject( hdc, dib );

    surface->funcs->lock( surface );

    if (info->prcDirty)
    {
        IntersectRect( &rect, &rect, info->prcDirty );
        memcpy( src_bits, dst_bits, bmi->bmiHeader.biSizeImage );
        PatBlt( hdc, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, BLACKNESS );
    }
    src_rect = rect;
    if (info->pptSrc) OffsetRect( &src_rect, info->pptSrc->x, info->pptSrc->y );
    DPtoLP( info->hdcSrc, (POINT *)&src_rect, 2 );

    ret = GdiAlphaBlend( hdc, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top,
                         info->hdcSrc, src_rect.left, src_rect.top,
                         src_rect.right - src_rect.left, src_rect.bottom - src_rect.top,
                         (info->dwFlags & ULW_ALPHA) ? *info->pblend : blend );
    if (ret)
    {
        memcpy( dst_bits, src_bits, bmi->bmiHeader.biSizeImage );
        add_bounds_rect( surface->funcs->get_bounds( surface ), &rect );
    }

    surface->funcs->unlock( surface );
    surface->funcs->flush( surface );

done:
    window_surface_release( surface );
    if (hdc) DeleteDC( hdc );
    if (dib) DeleteObject( dib );
    return ret;
}


/**********************************************************************
 *           ANDROID_WindowMessage
 */
LRESULT CDECL ANDROID_WindowMessage( HWND hwnd, UINT msg, WPARAM wp, LPARAM lp )
{
    struct android_win_data *data;

    switch (msg)
    {
    case WM_ANDROID_REFRESH:
        if (wp)  /* opengl client window */
        {
            update_gl_drawable( hwnd );
        }
        else if ((data = get_win_data( hwnd )))
        {
            struct window_surface *surface = data->surface;
            if (surface)
            {
                surface->funcs->lock( surface );
                *surface->funcs->get_bounds( surface ) = surface->rect;
                surface->funcs->unlock( surface );
                if (is_argb_surface( surface )) surface->funcs->flush( surface );
            }
            release_win_data( data );
        }
        return 0;
    default:
        FIXME( "got window msg %x hwnd %p wp %lx lp %lx\n", msg, hwnd, wp, lp );
        return 0;
    }
}


/***********************************************************************
 *           ANDROID_create_desktop
 */
BOOL CDECL ANDROID_create_desktop( UINT width, UINT height )
{
    desktop_orig_wndproc = (WNDPROC)SetWindowLongPtrW( GetDesktopWindow(), GWLP_WNDPROC,
                                                       (LONG_PTR)desktop_wndproc_wrapper );

    /* wait until we receive the surface changed event */
    while (!screen_width)
    {
        if (wait_events( 2000 ) != 1)
        {
            ERR( "wait timed out\n" );
            break;
        }
        process_events( QS_ALLINPUT );
    }
    return TRUE;
}
