move around - flatter.
[profile/ivi/evas.git] / src / modules / engines / software_ddraw / evas_ddraw_main.cpp
1 #include "evas_common.h"
2 #include "evas_engine.h"
3
4 int
5 evas_software_ddraw_init (HWND    window,
6                           int     depth,
7                           Outbuf *buf)
8 {
9    DDSURFACEDESC  surface_desc;
10    DDPIXELFORMAT  pixel_format;
11    RECT           rect;
12    LPDIRECTDRAW   o;
13    HRESULT        res;
14    int            width;
15    int            height;
16
17    if (!buf)
18      return 0;
19
20    if (!GetClientRect(window, &rect))
21      return 0;
22
23    width = rect.right - rect.left;
24    height = rect.bottom - rect.top;
25
26    buf->priv.dd.window = window;
27
28    res = DirectDrawCreate(NULL, &buf->priv.dd.object, NULL);
29    if (FAILED(res))
30      return 0;
31
32    res = buf->priv.dd.object->SetCooperativeLevel(window, DDSCL_NORMAL);
33    if (FAILED(res))
34      goto release_object;
35
36    res = buf->priv.dd.object->CreateClipper (0, &buf->priv.dd.clipper, NULL);
37    if (FAILED(res))
38      goto release_object;
39
40    res = buf->priv.dd.clipper->SetHWnd (0, window);
41    if (FAILED(res))
42      goto release_clipper;
43
44    memset(&surface_desc, 0, sizeof(surface_desc));
45    surface_desc.dwSize = sizeof(surface_desc);
46    surface_desc.dwFlags = DDSD_CAPS;
47    surface_desc.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
48
49    res = buf->priv.dd.object->CreateSurface (&surface_desc, &buf->priv.dd.surface_primary, NULL);
50    if (FAILED(res))
51      goto release_clipper;
52
53    res = buf->priv.dd.surface_primary->SetClipper (buf->priv.dd.clipper);
54    if (FAILED(res))
55      goto release_surface_primary;
56
57    memset (&surface_desc, 0, sizeof(surface_desc));
58    surface_desc.dwSize = sizeof(surface_desc);
59    surface_desc.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
60    surface_desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
61    surface_desc.dwWidth = width;
62    surface_desc.dwHeight = height;
63
64    res = buf->priv.dd.object->CreateSurface (&surface_desc, &buf->priv.dd.surface_back, NULL);
65    if (FAILED(res))
66      goto release_surface_primary;
67
68    ZeroMemory(&pixel_format, sizeof(pixel_format));
69    pixel_format.dwSize = sizeof(pixel_format);
70    buf->priv.dd.surface_primary->GetPixelFormat(&pixel_format);
71
72    if (pixel_format.dwRGBBitCount != depth)
73      goto release_surface_back;
74
75    buf->priv.dd.depth = depth;
76
77    return 1;
78
79  release_surface_back:
80    buf->priv.dd.surface_back->Release();
81  release_surface_primary:
82    buf->priv.dd.surface_primary->Release();
83  release_clipper:
84    buf->priv.dd.clipper->Release();
85  release_object:
86    buf->priv.dd.object->Release();
87
88    return 0;
89 }
90
91 void
92 evas_software_ddraw_shutdown(Outbuf *buf)
93 {
94    if (!buf)
95      return;
96
97    buf->priv.dd.surface_back->Release();
98    buf->priv.dd.surface_primary->Release();
99    buf->priv.dd.clipper->Release();
100    buf->priv.dd.object->Release();
101 }
102
103 int
104 evas_software_ddraw_masks_get(Outbuf *buf)
105 {
106    DDPIXELFORMAT pixel_format;
107
108    ZeroMemory(&pixel_format, sizeof(pixel_format));
109    pixel_format.dwSize = sizeof(pixel_format);
110
111    if (FAILED(buf->priv.dd.surface_primary->GetPixelFormat(&pixel_format)))
112      return 0;
113
114    buf->priv.mask.r = pixel_format.dwRBitMask;
115    buf->priv.mask.g = pixel_format.dwGBitMask;
116    buf->priv.mask.b = pixel_format.dwBBitMask;
117
118    return 1;
119 }
120
121 void *
122 evas_software_ddraw_lock(Outbuf *buf,
123                          int    *ddraw_width,
124                          int    *ddraw_height,
125                          int    *ddraw_pitch,
126                          int    *ddraw_depth)
127 {
128    DDSURFACEDESC surface_desc;
129
130    ZeroMemory(&surface_desc, sizeof(surface_desc));
131    surface_desc.dwSize = sizeof(surface_desc);
132
133    if (FAILED(buf->priv.dd.surface_back->Lock(NULL,
134                                               &surface_desc,
135                                               DDLOCK_WAIT | DDLOCK_SURFACEMEMORYPTR,
136                                               NULL)))
137      return NULL;
138
139    *ddraw_width = surface_desc.dwWidth;
140    *ddraw_height = surface_desc.dwHeight;
141    *ddraw_pitch = surface_desc.lPitch;
142    *ddraw_depth = surface_desc.ddpfPixelFormat.dwRGBBitCount >> 3;
143
144    return surface_desc.lpSurface;
145 }
146
147 void
148 evas_software_ddraw_unlock_and_flip(Outbuf *buf)
149 {
150    RECT    dst_rect;
151    RECT    src_rect;
152    POINT   p;
153
154    if (FAILED(buf->priv.dd.surface_back->Unlock(NULL)))
155      return;
156
157    /* we figure out where on the primary surface our window lives */
158    p.x = 0;
159    p.y = 0;
160    ClientToScreen(buf->priv.dd.window, &p);
161    GetClientRect(buf->priv.dd.window, &dst_rect);
162    OffsetRect(&dst_rect, p.x, p.y);
163    SetRect(&src_rect, 0, 0, buf->width, buf->height);
164
165    /* nothing to do if the function fails, so we don't check the result */
166    buf->priv.dd.surface_primary->Blt(&dst_rect,
167                                      buf->priv.dd.surface_back,
168                                      &src_rect,
169                                      DDBLT_WAIT, NULL);
170 }
171
172 void
173 evas_software_ddraw_surface_resize(Outbuf *buf)
174 {
175    DDSURFACEDESC surface_desc;
176
177    buf->priv.dd.surface_back->Release();
178    memset (&surface_desc, 0, sizeof (surface_desc));
179    surface_desc.dwSize = sizeof (surface_desc);
180    /* FIXME: that code does not compile. Must know why */
181 #if 0
182    surface_desc.dwFlags = DDSD_HEIGHT | DDSD_WIDTH;
183    surface_desc.dwWidth = width;
184    surface_desc.dwHeight = height;
185    buf->priv.dd.surface_back->SetSurfaceDesc(&surface_desc, NULL);
186 #else
187    surface_desc.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
188    surface_desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
189    surface_desc.dwWidth = buf->width;
190    surface_desc.dwHeight = buf->height;
191    buf->priv.dd.object->CreateSurface(&surface_desc,
192                                       &buf->priv.dd.surface_back,
193                                       NULL);
194 #endif
195 }