efl/legacy/evas/src/modules/engines/software_ddraw/evas_ddraw_main.cpp

249 lines
7.5 KiB
C++

#include "evas_common.h"
#include "evas_engine.h"
int
evas_software_ddraw_init (HWND window,
int depth,
int fullscreen,
Outbuf *buf)
{
DDSURFACEDESC surface_desc;
DDPIXELFORMAT pixel_format;
HRESULT res;
int width;
int height;
if (!buf)
return 0;
buf->priv.dd.window = window;
res = DirectDrawCreate(NULL, &buf->priv.dd.object, NULL);
if (FAILED(res))
return 0;
if (buf->priv.dd.fullscreen)
{
DDSCAPS caps;
res = buf->priv.dd.object->SetCooperativeLevel(window,
DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
if (FAILED(res))
goto release_object;
width = GetSystemMetrics(SM_CXSCREEN);
height = GetSystemMetrics(SM_CYSCREEN);
ZeroMemory(&pixel_format, sizeof(pixel_format));
pixel_format.dwSize = sizeof(pixel_format);
buf->priv.dd.surface_primary->GetPixelFormat(&pixel_format);
if (pixel_format.dwRGBBitCount != (DWORD)depth)
goto release_object;
buf->priv.dd.depth = depth;
res = buf->priv.dd.object->SetDisplayMode(width, height, depth);
if (FAILED(res))
goto release_object;
memset(&surface_desc, 0, sizeof(surface_desc));
surface_desc.dwSize = sizeof(surface_desc);
surface_desc.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;
surface_desc.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_FLIP | DDSCAPS_COMPLEX;
surface_desc.dwBackBufferCount = 1;
res = buf->priv.dd.object->CreateSurface(&surface_desc,
&buf->priv.dd.surface_primary, NULL);
if (FAILED(res))
goto release_object;
caps.dwCaps = DDSCAPS_BACKBUFFER;
res = buf->priv.dd.surface_primary->GetAttachedSurface(&caps,
&buf->priv.dd.surface_back);
if (FAILED(res))
goto release_surface_primary;
}
else
{
RECT rect;
if (!GetClientRect(window, &rect))
goto release_object;
width = rect.right - rect.left;
height = rect.bottom - rect.top;
res = buf->priv.dd.object->SetCooperativeLevel(window, DDSCL_NORMAL);
if (FAILED(res))
goto release_object;
res = buf->priv.dd.object->CreateClipper(0, &buf->priv.dd.clipper, NULL);
if (FAILED(res))
goto release_object;
res = buf->priv.dd.clipper->SetHWnd(0, window);
if (FAILED(res))
goto release_clipper;
memset(&surface_desc, 0, sizeof(surface_desc));
surface_desc.dwSize = sizeof(surface_desc);
surface_desc.dwFlags = DDSD_CAPS;
surface_desc.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
res = buf->priv.dd.object->CreateSurface(&surface_desc, &buf->priv.dd.surface_primary, NULL);
if (FAILED(res))
goto release_clipper;
res = buf->priv.dd.surface_primary->SetClipper(buf->priv.dd.clipper);
if (FAILED(res))
goto release_surface_primary;
memset (&surface_desc, 0, sizeof(surface_desc));
surface_desc.dwSize = sizeof(surface_desc);
surface_desc.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
surface_desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
surface_desc.dwWidth = width;
surface_desc.dwHeight = height;
res = buf->priv.dd.object->CreateSurface(&surface_desc, &buf->priv.dd.surface_back, NULL);
if (FAILED(res))
goto release_surface_primary;
ZeroMemory(&pixel_format, sizeof(pixel_format));
pixel_format.dwSize = sizeof(pixel_format);
buf->priv.dd.surface_primary->GetPixelFormat(&pixel_format);
if (pixel_format.dwRGBBitCount != (DWORD)depth)
goto release_surface_back;
buf->priv.dd.depth = depth;
}
return 1;
release_surface_back:
buf->priv.dd.surface_back->Release();
release_surface_primary:
buf->priv.dd.surface_primary->Release();
release_clipper:
if (!buf->priv.dd.fullscreen)
buf->priv.dd.clipper->Release();
release_object:
buf->priv.dd.object->Release();
return 0;
}
void
evas_software_ddraw_shutdown(Outbuf *buf)
{
if (!buf)
return;
if (buf->priv.dd.fullscreen)
if (buf->priv.dd.surface_back)
buf->priv.dd.surface_back->Release();
if (buf->priv.dd.surface_primary)
buf->priv.dd.surface_primary->Release();
if (!buf->priv.dd.fullscreen)
if (buf->priv.dd.clipper)
buf->priv.dd.clipper->Release();
if (buf->priv.dd.object)
buf->priv.dd.object->Release();
}
int
evas_software_ddraw_masks_get(Outbuf *buf)
{
DDPIXELFORMAT pixel_format;
ZeroMemory(&pixel_format, sizeof(pixel_format));
pixel_format.dwSize = sizeof(pixel_format);
if (FAILED(buf->priv.dd.surface_primary->GetPixelFormat(&pixel_format)))
return 0;
buf->priv.mask.r = pixel_format.dwRBitMask;
buf->priv.mask.g = pixel_format.dwGBitMask;
buf->priv.mask.b = pixel_format.dwBBitMask;
return 1;
}
void *
evas_software_ddraw_lock(Outbuf *buf,
int *ddraw_width,
int *ddraw_height,
int *ddraw_pitch,
int *ddraw_depth)
{
DDSURFACEDESC surface_desc;
ZeroMemory(&surface_desc, sizeof(surface_desc));
surface_desc.dwSize = sizeof(surface_desc);
if (FAILED(buf->priv.dd.surface_back->Lock(NULL,
&surface_desc,
DDLOCK_WAIT | DDLOCK_WRITEONLY | DDLOCK_SURFACEMEMORYPTR | DDLOCK_NOSYSLOCK,
NULL)))
return NULL;
*ddraw_width = surface_desc.dwWidth;
*ddraw_height = surface_desc.dwHeight;
*ddraw_pitch = surface_desc.lPitch;
*ddraw_depth = surface_desc.ddpfPixelFormat.dwRGBBitCount >> 3;
return surface_desc.lpSurface;
}
void
evas_software_ddraw_unlock_and_flip(Outbuf *buf)
{
RECT dst_rect;
RECT src_rect;
POINT p;
if (FAILED(buf->priv.dd.surface_back->Unlock(NULL)))
return;
/* we figure out where on the primary surface our window lives */
p.x = 0;
p.y = 0;
ClientToScreen(buf->priv.dd.window, &p);
GetClientRect(buf->priv.dd.window, &dst_rect);
OffsetRect(&dst_rect, p.x, p.y);
SetRect(&src_rect, 0, 0, buf->width, buf->height);
/* nothing to do if the function fails, so we don't check the result */
buf->priv.dd.surface_primary->Blt(&dst_rect,
buf->priv.dd.surface_back,
&src_rect,
DDBLT_WAIT, NULL);
}
void
evas_software_ddraw_surface_resize(Outbuf *buf)
{
DDSURFACEDESC surface_desc;
buf->priv.dd.surface_back->Release();
memset (&surface_desc, 0, sizeof (surface_desc));
surface_desc.dwSize = sizeof (surface_desc);
/* FIXME: that code does not compile. Must know why */
#if 0
surface_desc.dwFlags = DDSD_HEIGHT | DDSD_WIDTH;
surface_desc.dwWidth = width;
surface_desc.dwHeight = height;
buf->priv.dd.surface_back->SetSurfaceDesc(&surface_desc, NULL);
#else
surface_desc.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
surface_desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
surface_desc.dwWidth = buf->width;
surface_desc.dwHeight = buf->height;
buf->priv.dd.object->CreateSurface(&surface_desc,
&buf->priv.dd.surface_back,
NULL);
#endif
}