Removed a few dependencies on kernel32 functions.
[wine] / dlls / ddraw / dsurface / dga.c
1 /*              DirectDrawSurface XF86DGA implementation
2  *
3  * Copyright 1997-2000 Marcus Meissner
4  * Copyright 1998-2000 Lionel Ulmer (most of Direct3D stuff)
5  */
6 #include "config.h"
7 #include "winerror.h"
8
9 #include <unistd.h>
10 #include <assert.h>
11 #include <fcntl.h>
12 #include <string.h>
13 #include <stdlib.h>
14 #include <stdio.h>
15
16 #include "debugtools.h"
17 #include "dga_private.h"
18 #include "bitmap.h"
19
20 DEFAULT_DEBUG_CHANNEL(ddraw);
21
22 #define DDPRIVATE(x) dga_dd_private *ddpriv = ((dga_dd_private*)(x)->d->private)
23 #define DPPRIVATE(x) dga_dp_private *dppriv = ((dga_dp_private*)(x)->private)
24 #define DSPRIVATE(x) dga_ds_private *dspriv = ((dga_ds_private*)(x)->private)
25
26 static BYTE DGA_TouchSurface(LPDIRECTDRAWSURFACE4 iface)
27 {
28     ICOM_THIS(IDirectDrawSurface4Impl,iface);
29     /* if the DIB section is in GdiMod state, we must
30      * touch the surface to get any updates from the DIB */
31     return *(BYTE*)(This->s.surface_desc.u1.lpSurface);
32 }
33
34 /******************************************************************************
35  *              IDirectDrawSurface methods
36  *
37  * Since DDS3 and DDS2 are supersets of DDS, we implement DDS3 and let
38  * DDS and DDS2 use those functions. (Function calls did not change (except
39  * using different DirectDrawSurfaceX version), just added flags and functions)
40  */
41
42 HRESULT WINAPI DGA_IDirectDrawSurface4Impl_Flip(
43     LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWSURFACE4 flipto,DWORD dwFlags
44 ) {
45     ICOM_THIS(IDirectDrawSurface4Impl,iface);
46     DSPRIVATE(This);
47     dga_ds_private      *fspriv;
48     IDirectDrawSurface4Impl* iflipto=(IDirectDrawSurface4Impl*)flipto;
49     DWORD               xheight;
50     LPBYTE              surf;
51
52     TRACE("(%p)->Flip(%p,%08lx)\n",This,iflipto,dwFlags);
53
54     DGA_TouchSurface(iface);
55     iflipto = _common_find_flipto(This,iflipto);
56
57     /* and flip! */
58     fspriv = (dga_ds_private*)iflipto->private;
59     TSXF86DGASetViewPort(display,DefaultScreen(display),0,fspriv->fb_height);
60     if (iflipto->s.palette) {
61         DPPRIVATE(iflipto);
62         
63         if (dppriv->cm)
64             TSXF86DGAInstallColormap(display,DefaultScreen(display),dppriv->cm);
65     }
66     while (!TSXF86DGAViewPortChanged(display,DefaultScreen(display),2)) {
67         /* EMPTY */
68     }
69     /* We need to switch the lowlevel surfaces, for DGA this is: */
70
71     /* The height within the framebuffer */
72     xheight             = dspriv->fb_height;
73     dspriv->fb_height   = fspriv->fb_height;
74     fspriv->fb_height   = xheight;
75
76     /* And the assciated surface pointer */
77     surf                                = This->s.surface_desc.u1.lpSurface;
78     This->s.surface_desc.u1.lpSurface   = iflipto->s.surface_desc.u1.lpSurface;
79     iflipto->s.surface_desc.u1.lpSurface= surf;
80     return DD_OK;
81 }
82
83 HRESULT WINAPI DGA_IDirectDrawSurface4Impl_SetPalette(
84     LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWPALETTE pal
85 ) {
86     ICOM_THIS(IDirectDrawSurface4Impl,iface);
87     IDirectDrawPaletteImpl* ipal=(IDirectDrawPaletteImpl*)pal;
88
89     TRACE("(%p)->(%p)\n",This,ipal);
90
91     /* According to spec, we are only supposed to 
92      * AddRef if this is not the same palette.
93      */
94     if( This->s.palette != ipal ) {
95         dga_dp_private  *fppriv;
96         if( ipal != NULL )
97             IDirectDrawPalette_AddRef( (IDirectDrawPalette*)ipal );
98         if( This->s.palette != NULL )
99             IDirectDrawPalette_Release( (IDirectDrawPalette*)This->s.palette );
100         This->s.palette = ipal;
101         fppriv = (dga_dp_private*)This->s.palette->private;
102
103         if (!fppriv->cm &&
104             (This->s.ddraw->d->screen_pixelformat.u.dwRGBBitCount<=8) ) {
105           int i;
106           
107           /* Delayed palette creation */
108           fppriv->cm = TSXCreateColormap(display,DefaultRootWindow(display),
109                                          DefaultVisualOfScreen(X11DRV_GetXScreen()),AllocAll);
110             
111           for (i=0;i<256;i++) {
112             XColor xc;
113             
114             xc.red              = ipal->palents[i].peRed<<8;
115             xc.blue             = ipal->palents[i].peBlue<<8;
116             xc.green    = ipal->palents[i].peGreen<<8;
117             xc.flags    = DoRed|DoBlue|DoGreen;
118             xc.pixel    = i;
119             TSXStoreColor(display,fppriv->cm,&xc);
120           }
121         }
122
123         TSXF86DGAInstallColormap(display,DefaultScreen(display),fppriv->cm);
124
125         if (This->s.hdc != 0) {
126             /* hack: set the DIBsection color map */
127             BITMAPOBJ *bmp = (BITMAPOBJ *) GDI_GetObjPtr(This->s.DIBsection, BITMAP_MAGIC);
128             X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *)bmp->dib;
129             dib->colorMap = This->s.palette ? This->s.palette->screen_palents : NULL;
130             GDI_ReleaseObj(This->s.DIBsection);
131         }
132         TSXFlush(display);
133     }
134     return DD_OK;
135 }
136
137 ULONG WINAPI DGA_IDirectDrawSurface4Impl_Release(LPDIRECTDRAWSURFACE4 iface) {
138     ICOM_THIS(IDirectDrawSurface4Impl,iface);
139     DDPRIVATE(This->s.ddraw);
140     DSPRIVATE(This);
141
142     TRACE("(%p)->() decrementing from %lu.\n", This, This->ref );
143
144     if (--(This->ref))
145         return This->ref;
146
147     IDirectDraw2_Release((IDirectDraw2*)This->s.ddraw);
148     /* clear out of surface list */
149     if (ddpriv->fb_height == -1)
150         VirtualFree(This->s.surface_desc.u1.lpSurface, 0, MEM_RELEASE);
151     else
152         ddpriv->vpmask &= ~(1<<(dspriv->fb_height/ddpriv->fb_height));
153
154     /* Free the DIBSection (if any) */
155     if (This->s.hdc != 0) {
156         /* hack: restore the original DIBsection color map */    
157         BITMAPOBJ *bmp = (BITMAPOBJ *) GDI_GetObjPtr(This->s.DIBsection, BITMAP_MAGIC);
158         X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *)bmp->dib;
159         dib->colorMap = dspriv->oldDIBmap;
160         GDI_ReleaseObj(This->s.DIBsection);
161
162         SelectObject(This->s.hdc, This->s.holdbitmap);
163         DeleteDC(This->s.hdc);
164         DeleteObject(This->s.DIBsection);
165     }
166     /* Free the clipper if attached to this surface */
167     if( This->s.lpClipper )
168         IDirectDrawClipper_Release(This->s.lpClipper);
169     HeapFree(GetProcessHeap(),0,This);
170     return S_OK;
171 }
172
173 HRESULT WINAPI DGA_IDirectDrawSurface4Impl_Unlock(
174     LPDIRECTDRAWSURFACE4 iface,LPVOID surface
175 ) {
176     ICOM_THIS(IDirectDrawSurface4Impl,iface);
177     TRACE("(%p)->Unlock(%p)\n",This,surface);
178
179     /* in case this was called from ReleaseDC */
180     DGA_TouchSurface(iface);
181
182     return DD_OK;
183 }
184
185 HRESULT WINAPI DGA_IDirectDrawSurface4Impl_GetDC(LPDIRECTDRAWSURFACE4 iface,HDC* lphdc) {
186     ICOM_THIS(IDirectDrawSurface4Impl,iface);                                             
187     DSPRIVATE(This);
188     int was_ok = This->s.hdc != 0;
189     HRESULT result = IDirectDrawSurface4Impl_GetDC(iface,lphdc);
190     if (This->s.hdc && !was_ok) {                               
191         /* hack: take over the DIBsection color map */
192         BITMAPOBJ *bmp = (BITMAPOBJ *) GDI_GetObjPtr(This->s.DIBsection, BITMAP_MAGIC);
193         X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *)bmp->dib;
194         dspriv->oldDIBmap = dib->colorMap;
195         dib->colorMap = This->s.palette ? This->s.palette->screen_palents : NULL;
196         GDI_ReleaseObj(This->s.DIBsection);
197     }
198     return result;
199 }
200
201 ICOM_VTABLE(IDirectDrawSurface4) dga_dds4vt = 
202 {
203     ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
204     IDirectDrawSurface4Impl_QueryInterface,
205     IDirectDrawSurface4Impl_AddRef,
206     DGA_IDirectDrawSurface4Impl_Release,
207     IDirectDrawSurface4Impl_AddAttachedSurface,
208     IDirectDrawSurface4Impl_AddOverlayDirtyRect,
209     IDirectDrawSurface4Impl_Blt,
210     IDirectDrawSurface4Impl_BltBatch,
211     IDirectDrawSurface4Impl_BltFast,
212     IDirectDrawSurface4Impl_DeleteAttachedSurface,
213     IDirectDrawSurface4Impl_EnumAttachedSurfaces,
214     IDirectDrawSurface4Impl_EnumOverlayZOrders,
215     DGA_IDirectDrawSurface4Impl_Flip,
216     IDirectDrawSurface4Impl_GetAttachedSurface,
217     IDirectDrawSurface4Impl_GetBltStatus,
218     IDirectDrawSurface4Impl_GetCaps,
219     IDirectDrawSurface4Impl_GetClipper,
220     IDirectDrawSurface4Impl_GetColorKey,
221     DGA_IDirectDrawSurface4Impl_GetDC,
222     IDirectDrawSurface4Impl_GetFlipStatus,
223     IDirectDrawSurface4Impl_GetOverlayPosition,
224     IDirectDrawSurface4Impl_GetPalette,
225     IDirectDrawSurface4Impl_GetPixelFormat,
226     IDirectDrawSurface4Impl_GetSurfaceDesc,
227     IDirectDrawSurface4Impl_Initialize,
228     IDirectDrawSurface4Impl_IsLost,
229     IDirectDrawSurface4Impl_Lock,
230     IDirectDrawSurface4Impl_ReleaseDC,
231     IDirectDrawSurface4Impl_Restore,
232     IDirectDrawSurface4Impl_SetClipper,
233     IDirectDrawSurface4Impl_SetColorKey,
234     IDirectDrawSurface4Impl_SetOverlayPosition,
235     DGA_IDirectDrawSurface4Impl_SetPalette,
236     DGA_IDirectDrawSurface4Impl_Unlock,
237     IDirectDrawSurface4Impl_UpdateOverlay,
238     IDirectDrawSurface4Impl_UpdateOverlayDisplay,
239     IDirectDrawSurface4Impl_UpdateOverlayZOrder,
240     IDirectDrawSurface4Impl_GetDDInterface,
241     IDirectDrawSurface4Impl_PageLock,
242     IDirectDrawSurface4Impl_PageUnlock,
243     IDirectDrawSurface4Impl_SetSurfaceDesc,
244     IDirectDrawSurface4Impl_SetPrivateData,
245     IDirectDrawSurface4Impl_GetPrivateData,
246     IDirectDrawSurface4Impl_FreePrivateData,
247     IDirectDrawSurface4Impl_GetUniquenessValue,
248     IDirectDrawSurface4Impl_ChangeUniquenessValue
249 };