wined3d: Only link and use GLSL program if at least one GLSL shader is available.
[wine] / dlls / wined3d / palette.c
1 /*              DirectDraw - IDirectPalette base interface
2  *
3  * Copyright 1997-2000 Marcus Meissner
4  * Copyright 2000-2001 TransGaming Technologies Inc.
5  * Copyright 2006 Stefan Dösinger for CodeWeavers
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20  */
21 #include "config.h"
22 #include "winerror.h"
23 #include "wine/debug.h"
24
25 #include <assert.h>
26 #include <string.h>
27
28 #include "wined3d_private.h"
29
30 WINE_DEFAULT_DEBUG_CHANNEL(d3d);
31
32 #define SIZE_BITS (DDPCAPS_1BIT | DDPCAPS_2BIT | DDPCAPS_4BIT | DDPCAPS_8BIT)
33
34 static HRESULT  WINAPI IWineD3DPaletteImpl_QueryInterface(IWineD3DPalette *iface, REFIID refiid, void **obj) {
35     IWineD3DPaletteImpl *This = (IWineD3DPaletteImpl *)iface;
36     TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(refiid),obj);
37
38     if (IsEqualGUID(refiid, &IID_IUnknown)
39         || IsEqualGUID(refiid, &IID_IWineD3DPalette)) {
40         *obj = iface;
41         IWineD3DPalette_AddRef(iface);
42         return S_OK;
43     }
44     else {
45         *obj = NULL;
46         return E_NOINTERFACE;
47     }
48 }
49
50 static ULONG  WINAPI IWineD3DPaletteImpl_AddRef(IWineD3DPalette *iface) {
51     IWineD3DPaletteImpl *This = (IWineD3DPaletteImpl *)iface;
52     ULONG ref = InterlockedIncrement(&This->ref);
53
54     TRACE("(%p)->() incrementing from %lu.\n", This, ref - 1);
55
56     return ref;
57 }
58
59 static ULONG  WINAPI IWineD3DPaletteImpl_Release(IWineD3DPalette *iface) {
60     IWineD3DPaletteImpl *This = (IWineD3DPaletteImpl *)iface;
61     ULONG ref = InterlockedDecrement(&This->ref);
62
63     TRACE("(%p)->() decrementing from %lu.\n", This, ref + 1);
64
65     if (!ref) {
66         HeapFree(GetProcessHeap(), 0, This);
67         return 0;
68     }
69
70     return ref;
71 }
72
73 /* Not called from the vtable */
74 DWORD IWineD3DPaletteImpl_Size(DWORD dwFlags) {
75     switch (dwFlags & SIZE_BITS) {
76         case DDPCAPS_1BIT: return 2;
77         case DDPCAPS_2BIT: return 4;
78         case DDPCAPS_4BIT: return 16;
79         case DDPCAPS_8BIT: return 256;
80         default: assert(0); return 256;
81     }
82 }
83
84 static HRESULT  WINAPI IWineD3DPaletteImpl_GetEntries(IWineD3DPalette *iface, DWORD Flags, DWORD Start, DWORD Count, PALETTEENTRY *PalEnt) {
85     IWineD3DPaletteImpl *This = (IWineD3DPaletteImpl *)iface;
86
87     TRACE("(%p)->(%08lx,%ld,%ld,%p)\n",This,Flags,Start,Count,PalEnt);
88
89     if (Flags != 0) return WINED3DERR_INVALIDCALL; /* unchecked */
90     if (Start + Count > IWineD3DPaletteImpl_Size(This->Flags))
91         return WINED3DERR_INVALIDCALL;
92
93     if (This->Flags & DDPCAPS_8BITENTRIES)
94     {
95         unsigned int i;
96         LPBYTE entry = (LPBYTE)PalEnt;
97
98         for (i=Start; i < Count+Start; i++)
99             *entry++ = This->palents[i].peRed;
100     }
101     else
102         memcpy(PalEnt, This->palents+Start, Count * sizeof(PALETTEENTRY));
103
104     return WINED3D_OK;
105 }
106
107 static HRESULT  WINAPI IWineD3DPaletteImpl_SetEntries(IWineD3DPalette *iface, DWORD Flags, DWORD Start, DWORD Count, PALETTEENTRY *PalEnt)
108 {
109     IWineD3DPaletteImpl *This = (IWineD3DPaletteImpl *)iface;
110     ResourceList *res;
111
112     TRACE("(%p)->(%08lx,%ld,%ld,%p)\n",This,Flags,Start,Count,PalEnt);
113
114     if (This->Flags & DDPCAPS_8BITENTRIES) {
115         unsigned int i;
116         const BYTE* entry = (const BYTE*)PalEnt;
117
118         for (i=Start; i < Count+Start; i++)
119             This->palents[i].peRed = *entry++;
120     }
121     else {
122         memcpy(This->palents+Start, PalEnt, Count * sizeof(PALETTEENTRY));
123
124         if (This->hpal)
125             SetPaletteEntries(This->hpal, Start, Count, This->palents+Start);
126     }
127
128 #if 0
129     /* Now, if we are in 'depth conversion mode', update the screen palette */
130     /* FIXME: we need to update the image or we won't get palette fading. */
131     if (This->ddraw->d->palette_convert != NULL)
132         This->ddraw->d->palette_convert(palent,This->screen_palents,start,count);
133 #endif
134
135     /* If the palette is attached to the render target, update all render targets */
136
137     for(res = This->wineD3DDevice->resources; res != NULL; res=res->next) {
138         if(IWineD3DResource_GetType(res->resource) == D3DRTYPE_SURFACE) {
139             IWineD3DSurfaceImpl *impl = (IWineD3DSurfaceImpl *) res->resource;
140             if(impl->palette == This)
141                 IWineD3DSurface_RealizePalette( (IWineD3DSurface *) res->resource);
142         }
143     }
144
145     /* If the palette is the primary palette, set the entries to the device */
146     if(This->Flags & DDPCAPS_PRIMARYSURFACE) {
147         unsigned int i;
148         IWineD3DDeviceImpl *device = This->wineD3DDevice;
149         PALETTEENTRY *entry = PalEnt;
150
151         for(i = Start; i < Start+Count; i++) {
152             device->palettes[device->currentPalette][i] = *entry++;
153         }
154     }
155
156     return WINED3D_OK;
157 }
158
159 static HRESULT  WINAPI IWineD3DPaletteImpl_GetCaps(IWineD3DPalette *iface, DWORD *Caps) {
160     IWineD3DPaletteImpl *This = (IWineD3DPaletteImpl *)iface;
161     TRACE("(%p)->(%p)\n", This, Caps);
162
163     *Caps = This->Flags;
164     return WINED3D_OK;
165 }
166
167 static HRESULT  WINAPI IWineD3DPaletteImpl_GetParent(IWineD3DPalette *iface, IUnknown **Parent) {
168     IWineD3DPaletteImpl *This = (IWineD3DPaletteImpl *)iface;
169     TRACE("(%p)->(%p)\n", This, Parent);
170
171     *Parent = (IUnknown *) This->parent;
172     IUnknown_AddRef( (IUnknown *) This->parent);
173     return WINED3D_OK;
174 }
175
176 const IWineD3DPaletteVtbl IWineD3DPalette_Vtbl =
177 {
178     /*** IUnknown ***/
179     IWineD3DPaletteImpl_QueryInterface,
180     IWineD3DPaletteImpl_AddRef,
181     IWineD3DPaletteImpl_Release,
182     /*** IWineD3DPalette ***/
183     IWineD3DPaletteImpl_GetParent,
184     IWineD3DPaletteImpl_GetEntries,
185     IWineD3DPaletteImpl_GetCaps,
186     IWineD3DPaletteImpl_SetEntries
187 };