/*	User-based primary surface driver
 *
 * Copyright 2000-2001 TransGaming Technologies 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#include "config.h"

#include <assert.h>
#include <stdlib.h>
#include <string.h>

#define CONST_VTABLE

#include "winerror.h"
#include "wine/debug.h"
#include "ddraw_private.h"

WINE_DEFAULT_DEBUG_CHANNEL(ddraw);

/* if you use OWN_WINDOW, don't use SYNC_UPDATE, or you may get trouble */
/* #define SYNC_UPDATE */
/*
 * FIXME: This does not work any more because the created window has its own
 *        thread queue that cannot be manipulated by application threads.
 * #define OWN_WINDOW
 */

#ifdef OWN_WINDOW
static void User_create_own_window(IDirectDrawSurfaceImpl* This);
static void User_destroy_own_window(IDirectDrawSurfaceImpl* This);
#endif
#ifndef SYNC_UPDATE
static DWORD CALLBACK User_update_thread(LPVOID);
#endif
static void User_copy_to_screen(IDirectDrawSurfaceImpl* This, LPCRECT rc);

static HWND get_display_window(IDirectDrawSurfaceImpl* This, LPPOINT pt);

static const IDirectDrawSurface7Vtbl User_IDirectDrawSurface7_VTable;

HRESULT
User_DirectDrawSurface_Construct(IDirectDrawSurfaceImpl* This,
				 IDirectDrawImpl* pDD,
				 const DDSURFACEDESC2* pDDSD)
{
    USER_PRIV_VAR(priv, This);
    HRESULT hr;

    TRACE("(%p,%p,%p)\n",This,pDD,pDDSD);
    hr = DIB_DirectDrawSurface_Construct(This, pDD, pDDSD);
    if (FAILED(hr)) return hr;

    ICOM_INIT_INTERFACE(This, IDirectDrawSurface7,
			User_IDirectDrawSurface7_VTable);

    This->final_release = User_DirectDrawSurface_final_release;
    This->duplicate_surface = User_DirectDrawSurface_duplicate_surface;

    This->lock_update   = User_DirectDrawSurface_lock_update;
    This->unlock_update = User_DirectDrawSurface_unlock_update;

    This->flip_data   = User_DirectDrawSurface_flip_data;
    This->flip_update = User_DirectDrawSurface_flip_update;

    This->get_dc     = User_DirectDrawSurface_get_dc;
    This->release_dc = User_DirectDrawSurface_release_dc;

    This->set_palette    = User_DirectDrawSurface_set_palette;
    This->update_palette = User_DirectDrawSurface_update_palette;

    This->get_gamma_ramp = User_DirectDrawSurface_get_gamma_ramp;
    This->set_gamma_ramp = User_DirectDrawSurface_set_gamma_ramp;

    This->get_display_window = User_DirectDrawSurface_get_display_window;

    if (This->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)
    {
#ifdef OWN_WINDOW
	DirectDrawSurface_RegisterClass();
#endif
#ifndef SYNC_UPDATE
	InitializeCriticalSection(&priv->user.crit);
	priv->user.refresh_event = CreateEventW(NULL, TRUE, FALSE, NULL);
	priv->user.update_event = CreateEventW(NULL, FALSE, FALSE, NULL);
	priv->user.update_thread = CreateThread(NULL, 0, User_update_thread, This, 0, NULL);
#ifdef OWN_WINDOW
	if (This->ddraw_owner->cooperative_level & DDSCL_FULLSCREEN) {
	    /* wait for window creation (or update thread destruction) */
	    while (WaitForMultipleObjects(1, &priv->user.update_thread, FALSE, 100) == WAIT_TIMEOUT)
		if (This->more.lpDDRAWReserved) break;
	    if (!This->more.lpDDRAWReserved) {
		ERR("window creation failed\n");
	    }
	}
#endif
#else
#ifdef OWN_WINDOW
	User_create_own_window(This);
#endif
#endif
	if (!This->more.lpDDRAWReserved)
	    This->more.lpDDRAWReserved = (LPVOID)pDD->window;
    }

    return DIB_DirectDrawSurface_alloc_dc(This, &priv->user.cached_dc);
}

HRESULT
User_DirectDrawSurface_Create(IDirectDrawImpl *pDD,
			      const DDSURFACEDESC2 *pDDSD,
			      LPDIRECTDRAWSURFACE7 *ppSurf,
			      IUnknown *pUnkOuter)
{
    IDirectDrawSurfaceImpl* This;
    HRESULT hr;
    assert(pUnkOuter == NULL);

    This = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
		     sizeof(*This) + sizeof(User_DirectDrawSurfaceImpl));
    if (This == NULL) return E_OUTOFMEMORY;

    This->private = (User_DirectDrawSurfaceImpl*)(This+1);

    hr = User_DirectDrawSurface_Construct(This, pDD, pDDSD);
    if (FAILED(hr))
	HeapFree(GetProcessHeap(), 0, This);
    else
	*ppSurf = ICOM_INTERFACE(This, IDirectDrawSurface7);

    return hr;
}

void User_DirectDrawSurface_final_release(IDirectDrawSurfaceImpl* This)
{
    USER_PRIV_VAR(priv, This);

    if (This->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)
    {
#ifndef SYNC_UPDATE
	HANDLE event = priv->user.update_event;
	priv->user.update_event = 0;
	SetEvent(event);
	TRACE("waiting for update thread to terminate...\n");
#ifdef OWN_WINDOW
	/* dispatch any waiting sendmessages */
	{
	    MSG msg;
	    PeekMessageA(&msg, 0, 0, 0, PM_NOREMOVE);
	}
	/* to avoid deadlocks, allow SendMessages from update thread
	 * through while we wait for it */
	while (MsgWaitForMultipleObjects(1, &priv->user.update_thread, FALSE,
					 INFINITE, QS_SENDMESSAGE) == WAIT_OBJECT_0+1)
	{
	    MSG msg;
	    PeekMessageA(&msg, 0, 0, 0, PM_NOREMOVE);
	}
#else
	WaitForSingleObject(priv->user.update_thread,INFINITE);
#endif
	TRACE("update thread terminated\n");
	CloseHandle(event);
	CloseHandle(priv->user.update_thread);
	CloseHandle(priv->user.refresh_event);
	DeleteCriticalSection(&priv->user.crit);
#else
#ifdef OWN_WINDOW
	User_destroy_own_window(This);
#endif
#endif
	This->more.lpDDRAWReserved = 0;
#ifdef OWN_WINDOW
	DirectDrawSurface_UnregisterClass();
#endif
    }
    DIB_DirectDrawSurface_free_dc(This, priv->user.cached_dc);
    DIB_DirectDrawSurface_final_release(This);
}

static int User_DirectDrawSurface_init_wait(IDirectDrawSurfaceImpl* This)
{
    USER_PRIV_VAR(priv, This);
    int need_wait;
    EnterCriticalSection(&priv->user.crit);
    priv->user.wait_count++;
    need_wait = priv->user.in_refresh;
    LeaveCriticalSection(&priv->user.crit);
    return need_wait;
}

static void User_DirectDrawSurface_end_wait(IDirectDrawSurfaceImpl* This)
{
    USER_PRIV_VAR(priv, This);
    EnterCriticalSection(&priv->user.crit);
    if (!--priv->user.wait_count)
	ResetEvent(priv->user.refresh_event);
    LeaveCriticalSection(&priv->user.crit);
}

static void User_DirectDrawSurface_wait_update(IDirectDrawSurfaceImpl* This)
{
    USER_PRIV_VAR(priv, This);
    if (priv->user.in_refresh) {
	if (User_DirectDrawSurface_init_wait(This))
	    WaitForSingleObject(priv->user.refresh_event, 2);
	User_DirectDrawSurface_end_wait(This);
    }
}

void User_DirectDrawSurface_lock_update(IDirectDrawSurfaceImpl* This,
					LPCRECT pRect, DWORD dwFlags)
{
#if 0
    if (!(dwFlags & DDLOCK_WRITEONLY))
	User_copy_from_screen(This, pRect);
#endif
    if (dwFlags & DDLOCK_WAIT) User_DirectDrawSurface_wait_update(This);

    if (pRect) {
	This->lastlockrect = *pRect;
    } else {
	This->lastlockrect.left = This->lastlockrect.right = 0;
    }
}

void User_DirectDrawSurface_unlock_update(IDirectDrawSurfaceImpl* This,
					  LPCRECT pRect)
{
    if (This->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)
    {
#ifdef SYNC_UPDATE
	User_copy_to_screen(This, pRect);
#else
	USER_PRIV_VAR(priv, This);
	SetEvent(priv->user.update_event);
#endif
    }
}

void User_DirectDrawSurface_set_palette(IDirectDrawSurfaceImpl* This,
					IDirectDrawPaletteImpl* pal)
{
    USER_PRIV_VAR(priv, This);

    if (!pal) {
	FIXME("selecting null palette\n");
	/* I don't think selecting GDI object 0 will work, we should select
	 * the original palette, returned by the first SelectPalette */
	SelectPalette(priv->user.cached_dc, 0, FALSE);
	return;
    }

    SelectPalette(priv->user.cached_dc, pal->hpal, FALSE);

    DIB_DirectDrawSurface_set_palette(This, pal);
}

void User_DirectDrawSurface_update_palette(IDirectDrawSurfaceImpl* This,
					   IDirectDrawPaletteImpl* pal,
					   DWORD dwStart, DWORD dwCount,
					   LPPALETTEENTRY palent)
{
#ifndef SYNC_UPDATE
    USER_PRIV_VAR(priv, This);
#endif

    DIB_DirectDrawSurface_update_palette(This, pal, dwStart, dwCount, palent);
    /* FIXME: realize palette on display window */

#ifndef SYNC_UPDATE
    /* with async updates, it's probably cool to force an update */
    SetEvent(priv->user.update_event);
#endif
}

HRESULT User_DirectDrawSurface_duplicate_surface(IDirectDrawSurfaceImpl* This,
						 LPDIRECTDRAWSURFACE7* ppDup)
{
    return User_DirectDrawSurface_Create(This->ddraw_owner,
					 &This->surface_desc, ppDup, NULL);
}

BOOL User_DirectDrawSurface_flip_data(IDirectDrawSurfaceImpl* front,
				      IDirectDrawSurfaceImpl* back,
				      DWORD dwFlags)
{
    USER_PRIV_VAR(front_priv, front);
    USER_PRIV_VAR(back_priv, back);

    {
	HDC tmp;
	tmp = front_priv->user.cached_dc;
	front_priv->user.cached_dc = back_priv->user.cached_dc;
	back_priv->user.cached_dc = tmp;
    }

    return DIB_DirectDrawSurface_flip_data(front, back, dwFlags);
}

void User_DirectDrawSurface_flip_update(IDirectDrawSurfaceImpl* This, DWORD dwFlags)
{
#ifdef SYNC_UPDATE
    This->lastlockrect.left = This->lastlockrect.right = 0;
    assert(This->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE);
    User_copy_to_screen(This,NULL);
#else
    USER_PRIV_VAR(priv, This);
    assert(This->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE);
    if (dwFlags & DDFLIP_WAIT) User_DirectDrawSurface_wait_update(This);
    This->lastlockrect.left = This->lastlockrect.right = 0;
    SetEvent(priv->user.update_event);
#endif
}

HRESULT User_DirectDrawSurface_get_dc(IDirectDrawSurfaceImpl* This, HDC* phDC)
{
    USER_PRIV_VAR(priv, This);

    *phDC = priv->user.cached_dc;
    return S_OK;
}

HRESULT User_DirectDrawSurface_release_dc(IDirectDrawSurfaceImpl* This,
					  HDC hDC)
{
    return S_OK;
}

HRESULT User_DirectDrawSurface_get_gamma_ramp(IDirectDrawSurfaceImpl* This,
					      DWORD dwFlags,
					      LPDDGAMMARAMP lpGammaRamp)
{
    if (This->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)
    {
	POINT offset;
	HWND hDisplayWnd;
	HDC hDisplayDC;
	HRESULT hr;
	hDisplayWnd = get_display_window(This, &offset);
	hDisplayDC = GetDCEx(hDisplayWnd, 0, DCX_CLIPSIBLINGS|DCX_CACHE);
	hr = GetDeviceGammaRamp(hDisplayDC, lpGammaRamp) ? DD_OK : DDERR_UNSUPPORTED;
	ReleaseDC(hDisplayWnd, hDisplayDC);
	return hr;
    }
    return Main_DirectDrawSurface_get_gamma_ramp(This, dwFlags, lpGammaRamp);
}

HRESULT User_DirectDrawSurface_set_gamma_ramp(IDirectDrawSurfaceImpl* This,
					      DWORD dwFlags,
					      LPDDGAMMARAMP lpGammaRamp)
{
    if (This->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)
    {
	POINT offset;
	HWND hDisplayWnd;
	HDC hDisplayDC;
	HRESULT hr;
	hDisplayWnd = get_display_window(This, &offset);
	hDisplayDC = GetDCEx(hDisplayWnd, 0, DCX_CLIPSIBLINGS|DCX_CACHE);
	hr = SetDeviceGammaRamp(hDisplayDC, lpGammaRamp) ? DD_OK : DDERR_UNSUPPORTED;
	ReleaseDC(hDisplayWnd, hDisplayDC);
	return hr;
    }
    return Main_DirectDrawSurface_set_gamma_ramp(This, dwFlags, lpGammaRamp);
}

/* Returns the window that hosts the display.
 * *pt is set to the upper left position of the window relative to the
 * upper left corner of the surface. */
static HWND get_display_window(IDirectDrawSurfaceImpl* This, LPPOINT pt)
{
    memset(pt, 0, sizeof(*pt));

    if (This->ddraw_owner->cooperative_level & DDSCL_FULLSCREEN)
    {
#ifdef OWN_WINDOW
	USER_PRIV_VAR(priv, This);
#if 1
	SetWindowPos(priv->user.window, HWND_TOP, 0, 0, 0, 0,
		     SWP_DEFERERASE|SWP_NOACTIVATE|SWP_NOCOPYBITS|SWP_NOMOVE|
		     SWP_NOREDRAW|SWP_NOSENDCHANGING|SWP_NOSIZE);
#endif
	return priv->user.window;
#else
	return This->ddraw_owner->window;
#endif
    }
    else
    {
	if (This->clipper != NULL)
	{
	    /* looks silly, but since we don't have the clipper locked */
	    HWND hWnd = This->clipper->hWnd;

	    if (hWnd != 0)
	    {
		ClientToScreen(hWnd, pt);
		return hWnd;
	    }
	    else
	    {
		static BOOL warn = 0;
		if (!warn++) FIXME("clipper clip lists not supported\n");

		return GetDesktopWindow();
	    }
	}
	else
	{
	    static BOOL warn = 0;
	    if (!warn++) WARN("hosting on root\n");

	    return GetDesktopWindow();
	}
    }
}

HWND User_DirectDrawSurface_get_display_window(IDirectDrawSurfaceImpl* This)
{
    POINT offset;
    return get_display_window(This, &offset);
}

#ifdef OWN_WINDOW
static void User_create_own_window(IDirectDrawSurfaceImpl* This)
{
    USER_PRIV_VAR(priv, This);

    if (This->ddraw_owner->cooperative_level & DDSCL_FULLSCREEN)
    {
	priv->user.window = CreateWindowExA(WS_EX_TOPMOST |
					    WS_EX_LAYERED |
					    WS_EX_TRANSPARENT,
					    "WINE_DDRAW", "DirectDraw",
					    WS_POPUP,
					    0, 0,
					    This->surface_desc.dwWidth,
					    This->surface_desc.dwHeight,
					    GetDesktopWindow(),
					    0, 0, This);
	This->more.lpDDRAWReserved = (LPVOID)priv->user.window;
	SetWindowPos(priv->user.window, HWND_TOP, 0, 0, 0, 0,
		     SWP_DEFERERASE|SWP_NOACTIVATE|SWP_NOCOPYBITS|SWP_NOMOVE|
		     SWP_NOREDRAW|SWP_NOSENDCHANGING|SWP_NOSIZE|SWP_SHOWWINDOW);
	UpdateWindow(priv->user.window);
    }
}

static void User_destroy_own_window(IDirectDrawSurfaceImpl* This)
{
    USER_PRIV_VAR(priv, This);

    if (priv->user.window)
    {
	SetWindowPos(priv->user.window, 0, 0, 0, 0, 0,
		     SWP_DEFERERASE|SWP_NOACTIVATE|SWP_NOCOPYBITS|SWP_NOMOVE|SWP_NOZORDER|
		     SWP_NOREDRAW|SWP_NOSENDCHANGING|SWP_NOSIZE|SWP_HIDEWINDOW);
	This->more.lpDDRAWReserved = NULL;
	DestroyWindow(priv->user.window);
	priv->user.window = 0;
    }
}
#endif

#ifndef SYNC_UPDATE
static DWORD CALLBACK User_update_thread(LPVOID arg)
{
    IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)arg;
    USER_PRIV_VAR(priv, This);
    volatile HANDLE *pActive = (volatile HANDLE *)&priv->user.update_event;
    HANDLE event = *pActive;

#ifdef OWN_WINDOW
    User_create_own_window(This);
#endif

    /* the point of this is that many games lock the primary surface
     * multiple times per frame; this thread will then simply copy as
     * often as it can without keeping the main thread waiting for
     * each unlock, thus keeping the frame rate high */
    do {
#ifdef OWN_WINDOW
	DWORD ret = MsgWaitForMultipleObjects(1, &event, FALSE, INFINITE, QS_ALLINPUT);
	MSG msg;

	while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE))
	{
	    switch (msg.message) {
	    case WM_PAINT:
		DispatchMessageA(&msg);
		break;
	    default:
		/* since we risk getting keyboard messages posted to us,
		 * repost posted messages to cooperative window */
		PostMessageA(This->ddraw_owner->window, msg.message, msg.wParam, msg.lParam);
	    }
	}
#else
	DWORD ret = WaitForSingleObject(event, INFINITE);
#endif
	if (ret == WAIT_OBJECT_0)
	{
	    if (*pActive) {
		priv->user.in_refresh = TRUE;
		User_copy_to_screen(This, NULL);
		EnterCriticalSection(&priv->user.crit);
		priv->user.in_refresh = FALSE;
		if (priv->user.wait_count)
		    SetEvent(priv->user.refresh_event);
		LeaveCriticalSection(&priv->user.crit);
	    } else
		break;
	}
	else if (ret != WAIT_OBJECT_0+1) break;
    } while (TRUE);

    SetEvent(priv->user.refresh_event);
#ifdef OWN_WINDOW
    User_destroy_own_window(This);
#endif

    return 0;
}
#endif

static void User_copy_to_screen(IDirectDrawSurfaceImpl* This, LPCRECT rc)
{
    if (This->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)
    {
	POINT offset;
	HWND hDisplayWnd;
	HDC hDisplayDC;
	HDC hSurfaceDC;
	RECT drawrect;

	if (FAILED(This->get_dc(This, &hSurfaceDC)))
	    return;

	hDisplayWnd = get_display_window(This, &offset);
	hDisplayDC = GetDCEx(hDisplayWnd, 0, DCX_CLIPSIBLINGS|DCX_CACHE);
#if 0
	/* FIXME: this doesn't work... if users really want to run
	 * X in 8bpp, then we need to call directly into display.drv
	 * (or Wine's equivalent), and force a private colormap
	 * without default entries. */
	if (This->palette) {
	    SelectPalette(hDisplayDC, This->palette->hpal, FALSE);
	    RealizePalette(hDisplayDC); /* sends messages => deadlocks */
	}
#endif
	drawrect.left	= 0;
	drawrect.right	= This->surface_desc.dwWidth;
	drawrect.top	= 0;
	drawrect.bottom	= This->surface_desc.dwHeight;

	if (This->clipper) {
	    RECT xrc;
	    HWND hwnd = This->clipper->hWnd;
	    if (hwnd && GetClientRect(hwnd,&xrc)) {
		OffsetRect(&xrc,offset.x,offset.y);
		IntersectRect(&drawrect,&drawrect,&xrc);
	    }
	}
	if (rc)
	    IntersectRect(&drawrect,&drawrect,rc);
	else {
	    /* Only use this if the caller did not pass a rectangle, since
	     * due to double locking this could be the wrong one ... */
	    if (This->lastlockrect.left != This->lastlockrect.right)
		IntersectRect(&drawrect,&drawrect,&This->lastlockrect);
	}
	BitBlt(hDisplayDC,
		drawrect.left-offset.x, drawrect.top-offset.y,
		drawrect.right-drawrect.left, drawrect.bottom-drawrect.top,
		hSurfaceDC,
		drawrect.left, drawrect.top,
		SRCCOPY
	);
	ReleaseDC(hDisplayWnd, hDisplayDC);
    }
}

#if 0
static void User_copy_from_screen(IDirectDrawSurfaceImpl* This, LPCRECT rc)
{
    if (This->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)
    {
	POINT offset;
	HWND hDisplayWnd = get_display_window(This, &offset);
	HDC hDisplayDC = GetDC(hDisplayWnd);
	RECT drawrect;

	drawrect.left	= 0;
	drawrect.right	= This->surface_desc.dwWidth;
	drawrect.top	= 0;
	drawrect.bottom	= This->surface_desc.dwHeight;
	if (rc)
	    IntersectRect(&drawrect,&drawrect,rc);

	BitBlt(This->hDC,
	    drawrect.left, drawrect.top,
	    drawrect.right-drawrect.left, drawrect.bottom-drawrect.top,
	    hDisplayDC,
	    drawrect.left+offset.x, drawrect.top+offset.y,
	    SRCCOPY
	);
	ReleaseDC(hDisplayWnd, hDisplayDC);
    }
}
#endif

static const IDirectDrawSurface7Vtbl User_IDirectDrawSurface7_VTable =
{
    Main_DirectDrawSurface_QueryInterface,
    Main_DirectDrawSurface_AddRef,
    Main_DirectDrawSurface_Release,
    Main_DirectDrawSurface_AddAttachedSurface,
    Main_DirectDrawSurface_AddOverlayDirtyRect,
    DIB_DirectDrawSurface_Blt,
    Main_DirectDrawSurface_BltBatch,
    DIB_DirectDrawSurface_BltFast,
    Main_DirectDrawSurface_DeleteAttachedSurface,
    Main_DirectDrawSurface_EnumAttachedSurfaces,
    Main_DirectDrawSurface_EnumOverlayZOrders,
    Main_DirectDrawSurface_Flip,
    Main_DirectDrawSurface_GetAttachedSurface,
    Main_DirectDrawSurface_GetBltStatus,
    Main_DirectDrawSurface_GetCaps,
    Main_DirectDrawSurface_GetClipper,
    Main_DirectDrawSurface_GetColorKey,
    Main_DirectDrawSurface_GetDC,
    Main_DirectDrawSurface_GetFlipStatus,
    Main_DirectDrawSurface_GetOverlayPosition,
    Main_DirectDrawSurface_GetPalette,
    Main_DirectDrawSurface_GetPixelFormat,
    Main_DirectDrawSurface_GetSurfaceDesc,
    Main_DirectDrawSurface_Initialize,
    Main_DirectDrawSurface_IsLost,
    Main_DirectDrawSurface_Lock,
    Main_DirectDrawSurface_ReleaseDC,
    DIB_DirectDrawSurface_Restore,
    Main_DirectDrawSurface_SetClipper,
    Main_DirectDrawSurface_SetColorKey,
    Main_DirectDrawSurface_SetOverlayPosition,
    Main_DirectDrawSurface_SetPalette,
    Main_DirectDrawSurface_Unlock,
    Main_DirectDrawSurface_UpdateOverlay,
    Main_DirectDrawSurface_UpdateOverlayDisplay,
    Main_DirectDrawSurface_UpdateOverlayZOrder,
    Main_DirectDrawSurface_GetDDInterface,
    Main_DirectDrawSurface_PageLock,
    Main_DirectDrawSurface_PageUnlock,
    DIB_DirectDrawSurface_SetSurfaceDesc,
    Main_DirectDrawSurface_SetPrivateData,
    Main_DirectDrawSurface_GetPrivateData,
    Main_DirectDrawSurface_FreePrivateData,
    Main_DirectDrawSurface_GetUniquenessValue,
    Main_DirectDrawSurface_ChangeUniquenessValue,
    Main_DirectDrawSurface_SetPriority,
    Main_DirectDrawSurface_GetPriority,
    Main_DirectDrawSurface_SetLOD,
    Main_DirectDrawSurface_GetLOD
};
