Updated.
[wine] / dlls / ddraw / dsurface / dga2.c
1 /*      XF86DGA2 primary surface driver
2  *
3  * Copyright 2000 TransGaming Technologies Inc.
4  */
5
6 #include "config.h"
7
8 #ifdef HAVE_LIBXXF86DGA2
9
10 #include "ts_xlib.h"
11 #include "ts_xf86dga2.h"
12 #include "x11drv.h"
13 #include "winerror.h"
14
15 #include <assert.h>
16 #include <stdlib.h>
17
18 #include "debugtools.h"
19 #include "ddraw_private.h"
20 #include "ddraw/user.h"
21 #include "ddraw/dga2.h"
22 #include "dsurface/main.h"
23 #include "dsurface/dib.h"
24 #include "dsurface/dga2.h"
25
26 DEFAULT_DEBUG_CHANNEL(ddraw);
27
28 static ICOM_VTABLE(IDirectDrawSurface7) XF86DGA2_IDirectDrawSurface7_VTable;
29
30 HRESULT
31 XF86DGA2_DirectDrawSurface_Construct(IDirectDrawSurfaceImpl* This,
32                                      IDirectDrawImpl* pDD,
33                                      const DDSURFACEDESC2* pDDSD)
34 {
35     XF86DGA2_PRIV_VAR(priv, This);
36     XF86DGA2_DDRAW_PRIV_VAR(ddpriv, pDD);
37     HRESULT hr;
38     XDGADevice* mode;
39
40     TRACE("(%p,%p,%p)\n",This,pDD,pDDSD);
41     if (!ddpriv->xf86dga2.current_mode) {
42         /* we need a mode! */
43         hr = XF86DGA2_DirectDraw_SetDisplayMode(ICOM_INTERFACE(pDD, IDirectDraw7),
44                                                 pDD->width, pDD->height,
45                                                 pDD->pixelformat.u1.dwRGBBitCount,
46                                                 0, 0);
47         if (FAILED(hr)) return hr;
48     }
49
50     /* grab framebuffer data from current_mode */
51     mode = ddpriv->xf86dga2.current_mode;
52     priv->xf86dga2.fb_pitch = mode->mode.bytesPerScanline;
53     priv->xf86dga2.fb_vofs  = ddpriv->xf86dga2.next_vofs;
54     priv->xf86dga2.fb_addr  = mode->data +
55                               priv->xf86dga2.fb_pitch * priv->xf86dga2.fb_vofs;
56     TRACE("vofs=%ld, addr=%p\n", priv->xf86dga2.fb_vofs, priv->xf86dga2.fb_addr);
57
58     /* fill in surface_desc before we construct DIB from it */
59     This->surface_desc = *pDDSD;
60     This->surface_desc.lpSurface = priv->xf86dga2.fb_addr;
61     This->surface_desc.u1.lPitch = priv->xf86dga2.fb_pitch;
62     This->surface_desc.dwFlags |= DDSD_LPSURFACE | DDSD_PITCH;
63
64     hr = DIB_DirectDrawSurface_Construct(This, pDD, &This->surface_desc);
65     if (FAILED(hr)) return hr;
66
67     if (This->surface_desc.u4.ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED8) {
68         priv->xf86dga2.pal = TSXDGACreateColormap(display, DefaultScreen(display), mode, AllocAll);
69         TSXDGAInstallColormap(display, DefaultScreen(display), priv->xf86dga2.pal);
70     }
71
72     ddpriv->xf86dga2.next_vofs += pDDSD->dwHeight;
73
74     ICOM_INIT_INTERFACE(This, IDirectDrawSurface7,
75                         XF86DGA2_IDirectDrawSurface7_VTable);
76
77     This->final_release = XF86DGA2_DirectDrawSurface_final_release;
78     This->duplicate_surface = XF86DGA2_DirectDrawSurface_duplicate_surface;
79
80     This->flip_data   = XF86DGA2_DirectDrawSurface_flip_data;
81     This->flip_update = XF86DGA2_DirectDrawSurface_flip_update;
82
83     This->set_palette    = XF86DGA2_DirectDrawSurface_set_palette;
84     This->update_palette = XF86DGA2_DirectDrawSurface_update_palette;
85
86     This->get_display_window = XF86DGA2_DirectDrawSurface_get_display_window;
87
88     return DD_OK;
89 }
90
91 HRESULT
92 XF86DGA2_DirectDrawSurface_Create(IDirectDrawImpl *pDD,
93                               const DDSURFACEDESC2 *pDDSD,
94                               LPDIRECTDRAWSURFACE7 *ppSurf,
95                               IUnknown *pUnkOuter)
96 {
97     IDirectDrawSurfaceImpl* This;
98     HRESULT hr;
99     assert(pUnkOuter == NULL);
100
101     This = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
102                      sizeof(*This) + sizeof(XF86DGA2_DirectDrawSurfaceImpl));
103     if (This == NULL) return E_OUTOFMEMORY;
104
105     This->private = (XF86DGA2_DirectDrawSurfaceImpl*)(This+1);
106
107     hr = XF86DGA2_DirectDrawSurface_Construct(This, pDD, pDDSD);
108     if (FAILED(hr))
109         HeapFree(GetProcessHeap(), 0, This);
110     else
111         *ppSurf = ICOM_INTERFACE(This, IDirectDrawSurface7);
112
113     return hr;
114 }
115
116 void XF86DGA2_DirectDrawSurface_final_release(IDirectDrawSurfaceImpl* This)
117 {
118     XF86DGA2_PRIV_VAR(priv, This);
119
120     DIB_DirectDrawSurface_final_release(This);
121     if (priv->xf86dga2.pal)
122         TSXFreeColormap(display, priv->xf86dga2.pal);
123 }
124
125 void XF86DGA2_DirectDrawSurface_set_palette(IDirectDrawSurfaceImpl* This,
126                                         IDirectDrawPaletteImpl* pal) 
127 {
128     DIB_DirectDrawSurface_set_palette(This, pal);
129 }
130
131 void XF86DGA2_DirectDrawSurface_update_palette(IDirectDrawSurfaceImpl* This,
132                                            IDirectDrawPaletteImpl* pal,
133                                            DWORD dwStart, DWORD dwCount,
134                                            LPPALETTEENTRY palent)
135 {
136     XF86DGA2_PRIV_VAR(priv, This);
137
138     if (This->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)
139     {
140         XColor c;
141         int n;
142
143         c.flags = DoRed|DoGreen|DoBlue;
144         c.pixel = dwStart;
145         for (n=0; n<dwCount; n++,c.pixel++) {
146             c.red   = palent[n].peRed   << 8;
147             c.green = palent[n].peGreen << 8;
148             c.blue  = palent[n].peBlue  << 8;
149             TSXStoreColor(display, priv->xf86dga2.pal, &c);
150         }
151         TSXFlush(display);
152     }
153 }
154
155 HRESULT XF86DGA2_DirectDrawSurface_duplicate_surface(IDirectDrawSurfaceImpl* This,
156                                                  LPDIRECTDRAWSURFACE7* ppDup)
157 {
158     return XF86DGA2_DirectDrawSurface_Create(This->ddraw_owner,
159                                              &This->surface_desc, ppDup, NULL);
160 }
161
162 void XF86DGA2_DirectDrawSurface_flip_data(IDirectDrawSurfaceImpl* front,
163                                       IDirectDrawSurfaceImpl* back)
164 {
165     XF86DGA2_PRIV_VAR(front_priv, front);
166     XF86DGA2_PRIV_VAR(back_priv, back);
167
168     {
169         DWORD tmp;
170         tmp = front_priv->xf86dga2.fb_vofs;
171         front_priv->xf86dga2.fb_vofs = back_priv->xf86dga2.fb_vofs;
172         back_priv->xf86dga2.fb_vofs = tmp;
173     }
174     {
175         LPVOID tmp;
176         tmp = front_priv->xf86dga2.fb_addr;
177         front_priv->xf86dga2.fb_addr = back_priv->xf86dga2.fb_addr;
178         back_priv->xf86dga2.fb_addr = tmp;
179     }
180
181     DIB_DirectDrawSurface_flip_data(front, back);
182 }
183
184 void XF86DGA2_DirectDrawSurface_flip_update(IDirectDrawSurfaceImpl* This)
185 {
186     XF86DGA2_PRIV_VAR(priv, This);
187
188     /* XXX having the Flip's dwFlags would be nice here */
189     TSXDGASetViewport(display, DefaultScreen(display),
190                       0, priv->xf86dga2.fb_vofs, XDGAFlipImmediate);
191 }
192
193 HWND XF86DGA2_DirectDrawSurface_get_display_window(IDirectDrawSurfaceImpl* This)
194 {
195     /* there's a potential drawable in the ddraw object's current_mode->pixmap...
196      * perhaps it's possible to use it for the Direct3D rendering as well? */
197     return 0;
198 }
199
200 static ICOM_VTABLE(IDirectDrawSurface7) XF86DGA2_IDirectDrawSurface7_VTable =
201 {
202     Main_DirectDrawSurface_QueryInterface,
203     Main_DirectDrawSurface_AddRef,
204     Main_DirectDrawSurface_Release,
205     Main_DirectDrawSurface_AddAttachedSurface,
206     Main_DirectDrawSurface_AddOverlayDirtyRect,
207     DIB_DirectDrawSurface_Blt,
208     Main_DirectDrawSurface_BltBatch,
209     DIB_DirectDrawSurface_BltFast,
210     Main_DirectDrawSurface_DeleteAttachedSurface,
211     Main_DirectDrawSurface_EnumAttachedSurfaces,
212     Main_DirectDrawSurface_EnumOverlayZOrders,
213     Main_DirectDrawSurface_Flip,
214     Main_DirectDrawSurface_GetAttachedSurface,
215     Main_DirectDrawSurface_GetBltStatus,
216     Main_DirectDrawSurface_GetCaps,
217     Main_DirectDrawSurface_GetClipper,
218     Main_DirectDrawSurface_GetColorKey,
219     Main_DirectDrawSurface_GetDC,
220     Main_DirectDrawSurface_GetFlipStatus,
221     Main_DirectDrawSurface_GetOverlayPosition,
222     Main_DirectDrawSurface_GetPalette,
223     Main_DirectDrawSurface_GetPixelFormat,
224     Main_DirectDrawSurface_GetSurfaceDesc,
225     Main_DirectDrawSurface_Initialize,
226     Main_DirectDrawSurface_IsLost,
227     Main_DirectDrawSurface_Lock,
228     Main_DirectDrawSurface_ReleaseDC,
229     DIB_DirectDrawSurface_Restore,
230     Main_DirectDrawSurface_SetClipper,
231     Main_DirectDrawSurface_SetColorKey,
232     Main_DirectDrawSurface_SetOverlayPosition,
233     Main_DirectDrawSurface_SetPalette,
234     Main_DirectDrawSurface_Unlock,
235     Main_DirectDrawSurface_UpdateOverlay,
236     Main_DirectDrawSurface_UpdateOverlayDisplay,
237     Main_DirectDrawSurface_UpdateOverlayZOrder,
238     Main_DirectDrawSurface_GetDDInterface,
239     Main_DirectDrawSurface_PageLock,
240     Main_DirectDrawSurface_PageUnlock,
241     DIB_DirectDrawSurface_SetSurfaceDesc,
242     Main_DirectDrawSurface_SetPrivateData,
243     Main_DirectDrawSurface_GetPrivateData,
244     Main_DirectDrawSurface_FreePrivateData,
245     Main_DirectDrawSurface_GetUniquenessValue,
246     Main_DirectDrawSurface_ChangeUniquenessValue,
247     Main_DirectDrawSurface_SetPriority,
248     Main_DirectDrawSurface_GetPriority,
249     Main_DirectDrawSurface_SetLOD,
250     Main_DirectDrawSurface_GetLOD
251 };
252
253 #endif /* HAVE_LIBXXF86DGA2 */