Reenable device's default render states initialization.
[wine/multimedia.git] / dlls / x11drv / dga2.c
blob3b12b3d08679b7616937996b5ac1d961b411e682
1 /*
2 * DirectDraw DGA2 interface
4 * Copyright 2001 TransGaming Technologies, Inc.
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 #include "config.h"
23 #ifdef HAVE_LIBXXF86DGA2
25 #include "ts_xlib.h"
26 #include <X11/extensions/xf86dga.h>
28 #include "x11drv.h"
29 #include "x11ddraw.h"
30 #include "dga2.h"
32 #include "windef.h"
33 #include "wingdi.h"
34 #include "ddrawi.h"
35 #include "wine/debug.h"
37 WINE_DEFAULT_DEBUG_CHANNEL(x11drv);
39 extern int usedga;
41 LPDDHALMODEINFO xf86dga2_modes;
42 unsigned xf86dga2_mode_count;
43 static XDGAMode* modes;
44 static int dga_event, dga_error;
46 static void convert_mode(XDGAMode *mode, LPDDHALMODEINFO info)
48 info->dwWidth = mode->viewportWidth;
49 info->dwHeight = mode->viewportHeight;
50 info->wRefreshRate = mode->verticalRefresh;
51 info->lPitch = mode->bytesPerScanline;
52 info->dwBPP = (mode->depth < 24) ? mode->depth : mode->bitsPerPixel;
53 info->wFlags = (mode->depth == 8) ? DDMODEINFO_PALETTIZED : 0;
54 info->dwRBitMask = mode->redMask;
55 info->dwGBitMask = mode->greenMask;
56 info->dwBBitMask = mode->blueMask;
57 info->dwAlphaBitMask = 0;
58 TRACE(" width=%ld, height=%ld, bpp=%ld, refresh=%d\n",
59 info->dwWidth, info->dwHeight, info->dwBPP, info->wRefreshRate);
62 static int DGA2ErrorHandler(Display *dpy, XErrorEvent *event, void *arg)
64 return 1;
67 void X11DRV_XF86DGA2_Init(void)
69 int nmodes, major, minor, i;
70 Bool ok;
72 TRACE("\n");
74 if (xf86dga2_modes) return; /* already initialized? */
76 /* if in desktop mode, don't use DGA */
77 if (root_window != DefaultRootWindow(gdi_display)) return;
79 if (!usedga) return;
81 wine_tsx11_lock();
82 ok = XDGAQueryExtension(gdi_display, &dga_event, &dga_error);
83 if (ok)
85 X11DRV_expect_error(gdi_display, DGA2ErrorHandler, NULL);
86 ok = XDGAQueryVersion(gdi_display, &major, &minor);
87 if (X11DRV_check_error()) ok = FALSE;
89 wine_tsx11_unlock();
90 if (!ok) return;
92 if (major < 2) return; /* only bother with DGA 2+ */
94 /* test that it works */
95 wine_tsx11_lock();
96 X11DRV_expect_error(gdi_display, DGA2ErrorHandler, NULL);
97 ok = XDGAOpenFramebuffer(gdi_display, DefaultScreen(gdi_display));
98 if (X11DRV_check_error()) ok = FALSE;
99 if (ok)
101 XDGACloseFramebuffer(gdi_display, DefaultScreen(gdi_display));
102 /* retrieve modes */
103 modes = XDGAQueryModes(gdi_display, DefaultScreen(gdi_display), &nmodes);
104 if (!modes) ok = FALSE;
106 else WARN("disabling XF86DGA2 (insufficient permissions?)\n");
107 wine_tsx11_unlock();
108 if (!ok) return;
110 TRACE("DGA modes: count=%d\n", nmodes);
112 xf86dga2_mode_count = nmodes+1;
113 xf86dga2_modes = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(DDHALMODEINFO) * (nmodes+1));
115 /* make dummy mode for exiting DGA */
116 memset(&xf86dga2_modes[0], 0, sizeof(xf86dga2_modes[0]));
118 /* convert modes to DDHALMODEINFO format */
119 for (i=0; i<nmodes; i++)
120 convert_mode(&modes[i], &xf86dga2_modes[i+1]);
122 TRACE("Enabling XF86DGA2 mode\n");
125 void X11DRV_XF86DGA2_Cleanup(void)
127 if (modes) TSXFree(modes);
130 static XDGADevice *dga_dev;
132 static VIDMEM dga_mem = {
133 VIDMEM_ISRECTANGULAR | VIDMEM_ISHEAP
136 static DWORD PASCAL X11DRV_XF86DGA2_SetMode(LPDDHAL_SETMODEDATA data)
138 LPDDRAWI_DIRECTDRAW_LCL ddlocal = data->lpDD->lpExclusiveOwner;
139 DWORD vram;
140 Display *display = gdi_display;
142 data->ddRVal = DD_OK;
143 wine_tsx11_lock();
144 if (data->dwModeIndex) {
145 /* enter DGA */
146 XDGADevice *new_dev = NULL;
147 if (dga_dev || XDGAOpenFramebuffer(display, DefaultScreen(display)))
148 new_dev = XDGASetMode(display, DefaultScreen(display), modes[data->dwModeIndex-1].num);
149 if (new_dev) {
150 XDGASetViewport(display, DefaultScreen(display), 0, 0, XDGAFlipImmediate);
151 if (dga_dev) {
152 VirtualFree(dga_dev->data, 0, MEM_RELEASE);
153 XFree(dga_dev);
154 } else {
155 XDGASelectInput(display, DefaultScreen(display),
156 KeyPressMask|KeyReleaseMask|
157 ButtonPressMask|ButtonReleaseMask|
158 PointerMotionMask);
159 X11DRV_EVENT_SetDGAStatus((HWND)ddlocal->hWnd, dga_event);
160 X11DRV_EVENT_SetInputMethod(X11DRV_INPUT_RELATIVE);
162 dga_dev = new_dev;
163 vram = dga_dev->mode.bytesPerScanline * dga_dev->mode.imageHeight;
164 VirtualAlloc(dga_dev->data, vram, MEM_RESERVE|MEM_SYSTEM, PAGE_READWRITE);
165 dga_mem.fpStart = (FLATPTR)dga_dev->data;
166 dga_mem.u1.dwWidth = dga_dev->mode.bytesPerScanline;
167 dga_mem.u2.dwHeight = dga_dev->mode.imageHeight;
168 X11DRV_DDHAL_SwitchMode(data->dwModeIndex, dga_dev->data, &dga_mem);
169 X11DRV_DD_IsDirect = TRUE;
171 else {
172 ERR("failed\n");
173 if (!dga_dev) XDGACloseFramebuffer(display, DefaultScreen(display));
174 data->ddRVal = DDERR_GENERIC;
177 else if (dga_dev) {
178 /* exit DGA */
179 X11DRV_DD_IsDirect = FALSE;
180 X11DRV_DDHAL_SwitchMode(0, NULL, NULL);
181 XDGASetMode(display, DefaultScreen(display), 0);
182 VirtualFree(dga_dev->data, 0, MEM_RELEASE);
183 X11DRV_EVENT_SetInputMethod(X11DRV_INPUT_ABSOLUTE);
184 X11DRV_EVENT_SetDGAStatus(0, -1);
185 XFree(dga_dev);
186 XDGACloseFramebuffer(display, DefaultScreen(display));
187 dga_dev = NULL;
189 wine_tsx11_unlock();
190 return DDHAL_DRIVER_HANDLED;
193 static LPDDHAL_CREATESURFACE X11DRV_XF86DGA2_old_create_surface;
195 static DWORD PASCAL X11DRV_XF86DGA2_CreateSurface(LPDDHAL_CREATESURFACEDATA data)
197 LPDDRAWI_DDRAWSURFACE_LCL lcl = *data->lplpSList;
198 LPDDRAWI_DDRAWSURFACE_GBL gbl = lcl->lpGbl;
199 LPDDSURFACEDESC2 desc = (LPDDSURFACEDESC2)data->lpDDSurfaceDesc;
200 HRESULT hr = DDHAL_DRIVER_NOTHANDLED;
202 if (X11DRV_XF86DGA2_old_create_surface)
203 hr = X11DRV_XF86DGA2_old_create_surface(data);
205 if (desc->ddsCaps.dwCaps & (DDSCAPS_PRIMARYSURFACE | DDSCAPS_BACKBUFFER)) {
206 gbl->fpVidMem = 0; /* tell ddraw to allocate the memory */
207 hr = DDHAL_DRIVER_HANDLED;
209 return hr;
212 static DWORD PASCAL X11DRV_XF86DGA2_CreatePalette(LPDDHAL_CREATEPALETTEDATA data)
214 Display *display = gdi_display;
215 wine_tsx11_lock();
216 data->lpDDPalette->u1.dwReserved1 = XDGACreateColormap(display, DefaultScreen(display),
217 dga_dev, AllocAll);
218 wine_tsx11_unlock();
219 if (data->lpColorTable)
220 X11DRV_DDHAL_SetPalEntries(data->lpDDPalette->u1.dwReserved1, 0, 256,
221 data->lpColorTable);
222 data->ddRVal = DD_OK;
223 return DDHAL_DRIVER_HANDLED;
226 static DWORD PASCAL X11DRV_XF86DGA2_Flip(LPDDHAL_FLIPDATA data)
228 Display *display = gdi_display;
229 if (data->lpSurfCurr == X11DRV_DD_Primary) {
230 DWORD ofs = data->lpSurfCurr->lpGbl->fpVidMem - dga_mem.fpStart;
231 wine_tsx11_lock();
232 XDGASetViewport(display, DefaultScreen(display),
233 (ofs % dga_dev->mode.bytesPerScanline)*8/dga_dev->mode.bitsPerPixel,
234 ofs / dga_dev->mode.bytesPerScanline,
235 XDGAFlipImmediate);
236 wine_tsx11_unlock();
238 data->ddRVal = DD_OK;
239 return DDHAL_DRIVER_HANDLED;
242 static DWORD PASCAL X11DRV_XF86DGA2_SetPalette(LPDDHAL_SETPALETTEDATA data)
244 Display *display = gdi_display;
245 if ((data->lpDDSurface == X11DRV_DD_Primary) &&
246 data->lpDDPalette && data->lpDDPalette->u1.dwReserved1)
248 wine_tsx11_lock();
249 XDGAInstallColormap(display, DefaultScreen(display), data->lpDDPalette->u1.dwReserved1);
250 wine_tsx11_unlock();
252 data->ddRVal = DD_OK;
253 return DDHAL_DRIVER_HANDLED;
256 int X11DRV_XF86DGA2_CreateDriver(LPDDHALINFO info)
258 if (!xf86dga2_mode_count) return 0; /* no DGA */
260 info->dwNumModes = xf86dga2_mode_count;
261 info->lpModeInfo = xf86dga2_modes;
262 info->dwModeIndex = 0;
264 X11DRV_XF86DGA2_old_create_surface = info->lpDDCallbacks->CreateSurface;
265 info->lpDDCallbacks->SetMode = X11DRV_XF86DGA2_SetMode;
266 info->lpDDCallbacks->CreateSurface = X11DRV_XF86DGA2_CreateSurface;
267 info->lpDDCallbacks->CreatePalette = X11DRV_XF86DGA2_CreatePalette;
268 info->lpDDSurfaceCallbacks->Flip = X11DRV_XF86DGA2_Flip;
269 info->lpDDSurfaceCallbacks->SetPalette = X11DRV_XF86DGA2_SetPalette;
270 return TRUE;
273 #endif /* HAVE_LIBXXF86DGA2 */