/*
 * Mac driver window surface implementation
 *
 * Copyright 1993, 1994, 2011 Alexandre Julliard
 * Copyright 2006 Damjan Jovanovic
 * Copyright 2012, 2013 Ken Thomases for CodeWeavers, Inc.
 *
 * 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
 */

#include "config.h"

#include "macdrv.h"
#include "winuser.h"

WINE_DEFAULT_DEBUG_CHANNEL(macdrv);


/* 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);
}

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


struct macdrv_window_surface
{
    struct window_surface   header;
    macdrv_window           window;
    RECT                    bounds;
    HRGN                    region;
    HRGN                    drawn;
    BOOL                    use_alpha;
    RGNDATA                *blit_data;
    BYTE                   *bits;
    pthread_mutex_t         mutex;
    BITMAPINFO              info;   /* variable size, must be last */
};

static struct macdrv_window_surface *get_mac_surface(struct window_surface *surface)
{
    return (struct macdrv_window_surface *)surface;
}

/***********************************************************************
 *              update_blit_data
 */
static void update_blit_data(struct macdrv_window_surface *surface)
{
    HeapFree(GetProcessHeap(), 0, surface->blit_data);
    surface->blit_data = NULL;

    if (surface->drawn)
    {
        HRGN blit = CreateRectRgn(0, 0, 0, 0);

        if (CombineRgn(blit, surface->drawn, 0, RGN_COPY) > NULLREGION &&
            (!surface->region || CombineRgn(blit, blit, surface->region, RGN_AND) > NULLREGION) &&
            OffsetRgn(blit, surface->header.rect.left, surface->header.rect.top) > NULLREGION)
            surface->blit_data = get_region_data(blit, 0);

        DeleteObject(blit);
    }
}

/***********************************************************************
 *              macdrv_surface_lock
 */
static void macdrv_surface_lock(struct window_surface *window_surface)
{
    struct macdrv_window_surface *surface = get_mac_surface(window_surface);

    pthread_mutex_lock(&surface->mutex);
}

/***********************************************************************
 *              macdrv_surface_unlock
 */
static void macdrv_surface_unlock(struct window_surface *window_surface)
{
    struct macdrv_window_surface *surface = get_mac_surface(window_surface);

    pthread_mutex_unlock(&surface->mutex);
}

/***********************************************************************
 *              macdrv_surface_get_bitmap_info
 */
static void *macdrv_surface_get_bitmap_info(struct window_surface *window_surface,
                                            BITMAPINFO *info)
{
    struct macdrv_window_surface *surface = get_mac_surface(window_surface);

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

/***********************************************************************
 *              macdrv_surface_get_bounds
 */
static RECT *macdrv_surface_get_bounds(struct window_surface *window_surface)
{
    struct macdrv_window_surface *surface = get_mac_surface(window_surface);

    return &surface->bounds;
}

/***********************************************************************
 *              macdrv_surface_set_region
 */
static void macdrv_surface_set_region(struct window_surface *window_surface, HRGN region)
{
    struct macdrv_window_surface *surface = get_mac_surface(window_surface);

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

    window_surface->funcs->lock(window_surface);

    if (region)
    {
        if (!surface->region) surface->region = CreateRectRgn(0, 0, 0, 0);
        CombineRgn(surface->region, region, 0, RGN_COPY);
    }
    else
    {
        if (surface->region) DeleteObject(surface->region);
        surface->region = 0;
    }
    update_blit_data(surface);

    window_surface->funcs->unlock(window_surface);
}

/***********************************************************************
 *              macdrv_surface_flush
 */
static void macdrv_surface_flush(struct window_surface *window_surface)
{
    struct macdrv_window_surface *surface = get_mac_surface(window_surface);
    CGRect rect;
    HRGN region;

    window_surface->funcs->lock(window_surface);

    TRACE("flushing %p %s bounds %s bits %p\n", surface, wine_dbgstr_rect(&surface->header.rect),
          wine_dbgstr_rect(&surface->bounds), surface->bits);

    rect = cgrect_from_rect(surface->bounds);
    rect = CGRectOffset(rect, surface->header.rect.left, surface->header.rect.top);

    if (!IsRectEmpty(&surface->bounds) && (region = CreateRectRgnIndirect(&surface->bounds)))
    {
        if (surface->drawn)
        {
            CombineRgn(surface->drawn, surface->drawn, region, RGN_OR);
            DeleteObject(region);
        }
        else
            surface->drawn = region;
    }
    update_blit_data(surface);
    reset_bounds(&surface->bounds);

    window_surface->funcs->unlock(window_surface);

    if (!CGRectIsEmpty(rect))
        macdrv_window_needs_display(surface->window, rect);
}

/***********************************************************************
 *              macdrv_surface_destroy
 */
static void macdrv_surface_destroy(struct window_surface *window_surface)
{
    struct macdrv_window_surface *surface = get_mac_surface(window_surface);

    TRACE("freeing %p bits %p\n", surface, surface->bits);
    HeapFree(GetProcessHeap(), 0, surface->bits);
    pthread_mutex_destroy(&surface->mutex);
    HeapFree(GetProcessHeap(), 0, surface);
}

static const struct window_surface_funcs macdrv_surface_funcs =
{
    macdrv_surface_lock,
    macdrv_surface_unlock,
    macdrv_surface_get_bitmap_info,
    macdrv_surface_get_bounds,
    macdrv_surface_set_region,
    macdrv_surface_flush,
    macdrv_surface_destroy,
};

/***********************************************************************
 *              create_surface
 */
struct window_surface *create_surface(macdrv_window window, const RECT *rect,
                                      struct window_surface *old_surface, BOOL use_alpha)
{
    struct macdrv_window_surface *surface;
    struct macdrv_window_surface *old_mac_surface = get_mac_surface(old_surface);
    int width = rect->right - rect->left, height = rect->bottom - rect->top;
    DWORD *colors;
    pthread_mutexattr_t attr;
    int err;
    DWORD window_background;

    surface = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
                        FIELD_OFFSET(struct macdrv_window_surface, info.bmiColors[3]));
    if (!surface) return NULL;

    err = pthread_mutexattr_init(&attr);
    if (!err)
    {
        err = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
        if (!err)
            err = pthread_mutex_init(&surface->mutex, &attr);
        pthread_mutexattr_destroy(&attr);
    }
    if (err)
    {
        HeapFree(GetProcessHeap(), 0, surface);
        return NULL;
    }

    surface->info.bmiHeader.biSize        = sizeof(surface->info.bmiHeader);
    surface->info.bmiHeader.biWidth       = width;
    surface->info.bmiHeader.biHeight      = height; /* bottom-up */
    surface->info.bmiHeader.biPlanes      = 1;
    surface->info.bmiHeader.biBitCount    = 32;
    surface->info.bmiHeader.biSizeImage   = get_dib_image_size(&surface->info);
    surface->info.bmiHeader.biCompression = BI_RGB;
    surface->info.bmiHeader.biClrUsed     = 0;

    colors = (DWORD *)((char *)&surface->info + surface->info.bmiHeader.biSize);
    colors[0] = 0x00ff0000;
    colors[1] = 0x0000ff00;
    colors[2] = 0x000000ff;

    surface->header.funcs = &macdrv_surface_funcs;
    surface->header.rect  = *rect;
    surface->header.ref   = 1;
    surface->window = window;
    reset_bounds(&surface->bounds);
    if (old_mac_surface && old_mac_surface->drawn)
    {
        surface->drawn = CreateRectRgnIndirect(rect);
        OffsetRgn(surface->drawn, -rect->left, -rect->top);
        if (CombineRgn(surface->drawn, surface->drawn, old_mac_surface->drawn, RGN_AND) <= NULLREGION)
        {
            DeleteObject(surface->drawn);
            surface->drawn = 0;
        }
    }
    update_blit_data(surface);
    surface->use_alpha = use_alpha;
    surface->bits = HeapAlloc(GetProcessHeap(), 0, surface->info.bmiHeader.biSizeImage);
    if (!surface->bits) goto failed;
    window_background = macdrv_window_background_color();
    memset_pattern4(surface->bits, &window_background, surface->info.bmiHeader.biSizeImage);

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

    return &surface->header;

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

/***********************************************************************
 *              set_surface_use_alpha
 */
void set_surface_use_alpha(struct window_surface *window_surface, BOOL use_alpha)
{
    struct macdrv_window_surface *surface = get_mac_surface(window_surface);
    surface->use_alpha = use_alpha;
}

/***********************************************************************
 *              set_window_surface
 */
void set_window_surface(macdrv_window window, struct window_surface *window_surface)
{
    struct macdrv_window_surface *surface = get_mac_surface(window_surface);
    macdrv_set_window_surface(window, window_surface, surface ? &surface->mutex : NULL);
}

/***********************************************************************
 *              get_surface_blit_rects
 *
 * Caller must hold the surface lock.  Indirectly returns the surface
 * blit region rects.  Returns zero if the surface has nothing to blit;
 * returns non-zero if the surface does have rects to blit (drawn area
 * which isn't clipped away by a surface region).
 *
 * IMPORTANT: This function is called from non-Wine threads, so it
 *            must not use Win32 or Wine functions, including debug
 *            logging.
 */
int get_surface_blit_rects(void *window_surface, const CGRect **rects, int *count)
{
    struct macdrv_window_surface *surface = get_mac_surface(window_surface);

    if (surface->blit_data)
    {
        *rects = (const CGRect*)surface->blit_data->Buffer;
        *count = surface->blit_data->rdh.nCount;
    }
    else
    {
        *rects = NULL;
        *count = 0;
    }

    return (surface->blit_data != NULL);
}

/***********************************************************************
 *              create_surface_image
 *
 * Caller must hold the surface lock.  On input, *rect is the requested
 * image rect, relative to the window whole_rect, a.k.a. visible_rect.
 * On output, it's been intersected with that part backed by the surface
 * and is the actual size of the returned image.  copy_data indicates if
 * the caller will keep the returned image beyond the point where the
 * surface bits can be guaranteed to remain valid and unchanged.  If so,
 * the bits are copied instead of merely referenced by the image.
 *
 * IMPORTANT: This function is called from non-Wine threads, so it
 *            must not use Win32 or Wine functions, including debug
 *            logging.
 */
CGImageRef create_surface_image(void *window_surface, CGRect *rect, int copy_data)
{
    CGImageRef cgimage = NULL;
    struct macdrv_window_surface *surface = get_mac_surface(window_surface);
    int width, height;

    width  = surface->header.rect.right - surface->header.rect.left;
    height = surface->header.rect.bottom - surface->header.rect.top;
    *rect = CGRectIntersection(cgrect_from_rect(surface->header.rect), *rect);
    if (!CGRectIsEmpty(*rect))
    {
        CGRect visrect;
        CGColorSpaceRef colorspace;
        CGDataProviderRef provider;
        int bytes_per_row, offset, size;
        CGImageAlphaInfo alphaInfo;

        visrect = CGRectOffset(*rect, -surface->header.rect.left, -surface->header.rect.top);

        colorspace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB);
        bytes_per_row = get_dib_stride(width, 32);
        offset = CGRectGetMinX(visrect) * 4 + (height - CGRectGetMaxY(visrect)) * bytes_per_row;
        size = min(CGRectGetHeight(visrect) * bytes_per_row,
                   surface->info.bmiHeader.biSizeImage - offset);

        if (copy_data)
        {
            CFDataRef data = CFDataCreate(NULL, (UInt8*)surface->bits + offset, size);
            provider = CGDataProviderCreateWithCFData(data);
            CFRelease(data);
        }
        else
            provider = CGDataProviderCreateWithData(NULL, surface->bits + offset, size, NULL);

        alphaInfo = surface->use_alpha ? kCGImageAlphaPremultipliedFirst : kCGImageAlphaNoneSkipFirst;
        cgimage = CGImageCreate(CGRectGetWidth(visrect), CGRectGetHeight(visrect),
                                8, 32, bytes_per_row, colorspace,
                                alphaInfo | kCGBitmapByteOrder32Little,
                                provider, NULL, retina_on, kCGRenderingIntentDefault);
        CGDataProviderRelease(provider);
        CGColorSpaceRelease(colorspace);
    }

    return cgimage;
}

/***********************************************************************
 *              surface_clip_to_visible_rect
 *
 * Intersect the accumulated drawn region with a new visible rect,
 * effectively discarding stale drawing in the surface slack area.
 */
void surface_clip_to_visible_rect(struct window_surface *window_surface, const RECT *visible_rect)
{
    struct macdrv_window_surface *surface = get_mac_surface(window_surface);

    window_surface->funcs->lock(window_surface);

    if (surface->drawn)
    {
        RECT rect;
        HRGN region;

        rect = *visible_rect;
        OffsetRect(&rect, -rect.left, -rect.top);

        if ((region = CreateRectRgnIndirect(&rect)))
        {
            CombineRgn(surface->drawn, surface->drawn, region, RGN_AND);
            DeleteObject(region);

            update_blit_data(surface);
        }
    }

    window_surface->funcs->unlock(window_surface);
}
