2 * DirectDraw DGA2 interface
4 * Copyright 2001 TransGaming Technologies, Inc.
9 #ifdef HAVE_LIBXXF86DGA2
12 #include "ts_xf86dga2.h"
20 #include "debugtools.h"
22 DEFAULT_DEBUG_CHANNEL(x11drv
);
26 LPDDHALMODEINFO xf86dga2_modes
;
27 unsigned xf86dga2_mode_count
;
28 static XDGAMode
* modes
;
29 static int dga_event
, dga_error
;
31 static void convert_mode(XDGAMode
*mode
, LPDDHALMODEINFO info
)
33 info
->dwWidth
= mode
->viewportWidth
;
34 info
->dwHeight
= mode
->viewportHeight
;
35 info
->wRefreshRate
= mode
->verticalRefresh
;
36 info
->lPitch
= mode
->bytesPerScanline
;
37 info
->dwBPP
= (mode
->depth
< 24) ? mode
->depth
: mode
->bitsPerPixel
;
38 info
->wFlags
= (mode
->depth
== 8) ? DDMODEINFO_PALETTIZED
: 0;
39 info
->dwRBitMask
= mode
->redMask
;
40 info
->dwGBitMask
= mode
->greenMask
;
41 info
->dwBBitMask
= mode
->blueMask
;
42 info
->dwAlphaBitMask
= 0;
43 TRACE(" width=%ld, height=%ld, bpp=%ld, refresh=%d\n",
44 info
->dwWidth
, info
->dwHeight
, info
->dwBPP
, info
->wRefreshRate
);
47 void X11DRV_XF86DGA2_Init(void)
49 int nmodes
, major
, minor
, i
;
51 if (xf86dga2_modes
) return; /* already initialized? */
53 /* if in desktop mode, don't use DGA */
54 if (root_window
!= DefaultRootWindow(gdi_display
)) return;
58 if (!TSXDGAQueryExtension(gdi_display
, &dga_event
, &dga_error
)) return;
60 if (!TSXDGAQueryVersion(gdi_display
, &major
, &minor
)) return;
62 if (major
< 2) return; /* only bother with DGA 2+ */
64 /* test that it works */
65 if (!TSXDGAOpenFramebuffer(gdi_display
, DefaultScreen(gdi_display
))) {
66 WARN("disabling XF86DGA2 (insufficient permissions?)\n");
69 TSXDGACloseFramebuffer(gdi_display
, DefaultScreen(gdi_display
));
72 modes
= TSXDGAQueryModes(gdi_display
, DefaultScreen(gdi_display
), &nmodes
);
75 TRACE("DGA modes: count=%d\n", nmodes
);
77 xf86dga2_mode_count
= nmodes
+1;
78 xf86dga2_modes
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(DDHALMODEINFO
) * (nmodes
+1));
80 /* make dummy mode for exiting DGA */
81 memset(&xf86dga2_modes
[0], 0, sizeof(xf86dga2_modes
[0]));
83 /* convert modes to DDHALMODEINFO format */
84 for (i
=0; i
<nmodes
; i
++)
85 convert_mode(&modes
[i
], &xf86dga2_modes
[i
+1]);
87 TRACE("Enabling XF86DGA2 mode\n");
90 void X11DRV_XF86DGA2_Cleanup(void)
92 if (modes
) TSXFree(modes
);
95 static XDGADevice
*dga_dev
;
97 static VIDMEM dga_mem
= {
98 VIDMEM_ISRECTANGULAR
| VIDMEM_ISHEAP
101 static DWORD PASCAL
X11DRV_XF86DGA2_SetMode(LPDDHAL_SETMODEDATA data
)
103 LPDDRAWI_DIRECTDRAW_LCL ddlocal
= data
->lpDD
->lpExclusiveOwner
;
105 Display
*display
= gdi_display
;
107 data
->ddRVal
= DD_OK
;
108 if (data
->dwModeIndex
) {
110 XDGADevice
*new_dev
= NULL
;
111 if (dga_dev
|| TSXDGAOpenFramebuffer(display
, DefaultScreen(display
)))
112 new_dev
= TSXDGASetMode(display
, DefaultScreen(display
), modes
[data
->dwModeIndex
-1].num
);
114 TSXDGASetViewport(display
, DefaultScreen(display
), 0, 0, XDGAFlipImmediate
);
116 VirtualFree(dga_dev
->data
, 0, MEM_RELEASE
);
119 TSXDGASelectInput(display
, DefaultScreen(display
),
120 KeyPressMask
|KeyReleaseMask
|
121 ButtonPressMask
|ButtonReleaseMask
|
123 X11DRV_EVENT_SetDGAStatus(ddlocal
->hWnd
, dga_event
);
124 X11DRV_EVENT_SetInputMethod(X11DRV_INPUT_RELATIVE
);
127 vram
= dga_dev
->mode
.bytesPerScanline
* dga_dev
->mode
.imageHeight
;
128 VirtualAlloc(dga_dev
->data
, vram
, MEM_RESERVE
|MEM_SYSTEM
, PAGE_READWRITE
);
129 dga_mem
.fpStart
= (FLATPTR
)dga_dev
->data
;
130 dga_mem
.u1
.dwWidth
= dga_dev
->mode
.bytesPerScanline
;
131 dga_mem
.u2
.dwHeight
= dga_dev
->mode
.imageHeight
;
132 X11DRV_DDHAL_SwitchMode(data
->dwModeIndex
, dga_dev
->data
, &dga_mem
);
133 X11DRV_DD_IsDirect
= TRUE
;
137 if (!dga_dev
) TSXDGACloseFramebuffer(display
, DefaultScreen(display
));
138 data
->ddRVal
= DDERR_GENERIC
;
143 X11DRV_DD_IsDirect
= FALSE
;
144 X11DRV_DDHAL_SwitchMode(0, NULL
, NULL
);
145 TSXDGASetMode(display
, DefaultScreen(display
), 0);
146 VirtualFree(dga_dev
->data
, 0, MEM_RELEASE
);
147 X11DRV_EVENT_SetInputMethod(X11DRV_INPUT_ABSOLUTE
);
148 X11DRV_EVENT_SetDGAStatus(0, -1);
150 TSXDGACloseFramebuffer(display
, DefaultScreen(display
));
153 return DDHAL_DRIVER_HANDLED
;
156 static LPDDHAL_CREATESURFACE X11DRV_XF86DGA2_old_create_surface
;
158 static DWORD PASCAL
X11DRV_XF86DGA2_CreateSurface(LPDDHAL_CREATESURFACEDATA data
)
160 LPDDRAWI_DDRAWSURFACE_LCL lcl
= *data
->lplpSList
;
161 LPDDRAWI_DDRAWSURFACE_GBL gbl
= lcl
->lpGbl
;
162 LPDDSURFACEDESC2 desc
= (LPDDSURFACEDESC2
)data
->lpDDSurfaceDesc
;
163 HRESULT hr
= DDHAL_DRIVER_NOTHANDLED
;
165 if (X11DRV_XF86DGA2_old_create_surface
)
166 hr
= X11DRV_XF86DGA2_old_create_surface(data
);
168 if (desc
->ddsCaps
.dwCaps
& (DDSCAPS_PRIMARYSURFACE
| DDSCAPS_BACKBUFFER
)) {
169 gbl
->fpVidMem
= 0; /* tell ddraw to allocate the memory */
170 hr
= DDHAL_DRIVER_HANDLED
;
175 static DWORD PASCAL
X11DRV_XF86DGA2_CreatePalette(LPDDHAL_CREATEPALETTEDATA data
)
177 Display
*display
= gdi_display
;
178 data
->lpDDPalette
->u1
.dwReserved1
= TSXDGACreateColormap(display
, DefaultScreen(display
), dga_dev
, AllocAll
);
179 if (data
->lpColorTable
)
180 X11DRV_DDHAL_SetPalEntries(data
->lpDDPalette
->u1
.dwReserved1
, 0, 256,
182 data
->ddRVal
= DD_OK
;
183 return DDHAL_DRIVER_HANDLED
;
186 static DWORD PASCAL
X11DRV_XF86DGA2_Flip(LPDDHAL_FLIPDATA data
)
188 Display
*display
= gdi_display
;
189 if (data
->lpSurfCurr
== X11DRV_DD_Primary
) {
190 DWORD ofs
= data
->lpSurfCurr
->lpGbl
->fpVidMem
- dga_mem
.fpStart
;
191 TSXDGASetViewport(display
, DefaultScreen(display
),
192 (ofs
% dga_dev
->mode
.bytesPerScanline
)*8/dga_dev
->mode
.bitsPerPixel
,
193 ofs
/ dga_dev
->mode
.bytesPerScanline
,
196 data
->ddRVal
= DD_OK
;
197 return DDHAL_DRIVER_HANDLED
;
200 static DWORD PASCAL
X11DRV_XF86DGA2_SetPalette(LPDDHAL_SETPALETTEDATA data
)
202 Display
*display
= gdi_display
;
203 if ((data
->lpDDSurface
== X11DRV_DD_Primary
) &&
204 data
->lpDDPalette
&& data
->lpDDPalette
->u1
.dwReserved1
) {
205 TSXDGAInstallColormap(display
, DefaultScreen(display
), data
->lpDDPalette
->u1
.dwReserved1
);
207 data
->ddRVal
= DD_OK
;
208 return DDHAL_DRIVER_HANDLED
;
211 int X11DRV_XF86DGA2_CreateDriver(LPDDHALINFO info
)
213 if (!xf86dga2_mode_count
) return 0; /* no DGA */
215 info
->dwNumModes
= xf86dga2_mode_count
;
216 info
->lpModeInfo
= xf86dga2_modes
;
217 info
->dwModeIndex
= 0;
219 X11DRV_XF86DGA2_old_create_surface
= info
->lpDDCallbacks
->CreateSurface
;
220 info
->lpDDCallbacks
->SetMode
= X11DRV_XF86DGA2_SetMode
;
221 info
->lpDDCallbacks
->CreateSurface
= X11DRV_XF86DGA2_CreateSurface
;
222 info
->lpDDCallbacks
->CreatePalette
= X11DRV_XF86DGA2_CreatePalette
;
223 info
->lpDDSurfaceCallbacks
->Flip
= X11DRV_XF86DGA2_Flip
;
224 info
->lpDDSurfaceCallbacks
->SetPalette
= X11DRV_XF86DGA2_SetPalette
;
228 #endif /* HAVE_LIBXXF86DGA2 */