1 /* DirectDraw using DGA
3 * Copyright 1997-2000 Marcus Meissner
4 * Copyright 1998-2000 Lionel Ulmer (most of Direct3D stuff)
7 * When DirectVideo mode is enabled you can no longer use 'normal' X
8 * applications nor can you switch to a virtual console. Also, enabling
9 * only works, if you have switched to the screen where the application
11 * Some ways to debug this stuff are:
12 * - A terminal connected to the serial port. Can be bought used for cheap.
13 * (This is the method I am using.)
14 * - Another machine connected over some kind of network.
22 #ifdef HAVE_SYS_SIGNAL_H
23 # include <sys/signal.h>
33 #include "wine/exception.h"
36 #include "debugtools.h"
42 #include "dga_private.h"
44 #define RESTORE__SIGNALS
46 DEFAULT_DEBUG_CHANNEL(ddraw
);
48 #ifdef HAVE_LIBXXF86VM
49 XF86VidModeModeInfo
*orig_mode
= NULL
;
52 static inline BOOL
get_option( const char *name
, BOOL def
) {
53 return PROFILE_GetWineIniBool( "x11drv", name
, def
);
57 DDRAW_DGA_Available(void)
59 int fd
, evbase
, evret
, majver
, minver
;
60 static BYTE return_value
= 0xFF;
62 /* This prevents from probing X times for DGA */
63 if (return_value
!= 0xFF)
66 if (!get_option( "UseDGA", 1 )) {
67 TRACE("UseDGA disabled.\n");
72 /* First, query the extenstion and its version */
73 if (!TSXF86DGAQueryExtension(display
,&evbase
,&evret
)) {
74 TRACE("DGA extension not detected.\n");
79 if (!TSXF86DGAQueryVersion(display
,&majver
,&minver
)) {
80 TRACE("DGA version not detected.\n");
85 #ifdef HAVE_LIBXXF86DGA2
87 /* We have DGA 2.0 available ! */
88 if (TSXDGAOpenFramebuffer(display
, DefaultScreen(display
))) {
89 TSXDGACloseFramebuffer(display
, DefaultScreen(display
));
95 #endif /* defined(HAVE_LIBXXF86DGA2) */
97 /* You don't have to be root to use DGA extensions. Simply having access
98 * to /dev/mem will do the trick
99 * This can be achieved by adding the user to the "kmem" group on
100 * Debian 2.x systems, don't know about
103 if ((fd
= open("/dev/mem", O_RDWR
)) != -1)
109 TRACE("You have no access to /dev/mem\n");
116 DGA_Create( LPDIRECTDRAW
*lplpDD
) {
117 IDirectDrawImpl
* ddraw
;
118 dga_dd_private
* dgpriv
;
119 int memsize
,banksize
,major
,minor
,flags
;
125 /* Get DGA availability / version */
126 dga_version
= DDRAW_DGA_Available();
127 if (dga_version
== 0)
128 return DDERR_GENERIC
;
130 /* If we were just testing ... return OK */
134 ddraw
= (IDirectDrawImpl
*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(IDirectDrawImpl
));
135 *lplpDD
= (LPDIRECTDRAW
)ddraw
;
137 ICOM_VTBL(ddraw
) = &dga_ddvt
;
139 ddraw
->private = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(dga_dd_private
));
141 dgpriv
= (dga_dd_private
*)ddraw
->private;
142 #ifdef HAVE_LIBXXF86DGA2
143 if (dga_version
== 1) {
145 #endif /* defined(HAVE_LIBXXF86DGA2) */
146 TSXF86DGAQueryVersion(display
,&major
,&minor
);
147 TRACE("XF86DGA is version %d.%d\n",major
,minor
);
149 TSXF86DGAQueryDirectVideo(display
,DefaultScreen(display
),&flags
);
150 if (!(flags
& XF86DGADirectPresent
))
151 MESSAGE("direct video is NOT PRESENT.\n");
152 TSXF86DGAGetVideo(display
,DefaultScreen(display
),&addr
,&width
,&banksize
,&memsize
);
153 dgpriv
->fb_width
= width
;
154 TSXF86DGAGetViewPortSize(display
,DefaultScreen(display
),&width
,&height
);
155 TSXF86DGASetViewPort(display
,DefaultScreen(display
),0,0);
156 dgpriv
->fb_height
= height
;
157 TRACE("video framebuffer: begin %p, width %d,banksize %d,memsize %d\n",
158 addr
,width
,banksize
,memsize
160 TRACE("viewport height: %d\n",height
);
161 /* Get the screen dimensions as seen by Wine.
162 * In that case, it may be better to ignore the -desktop mode and
163 * return the real screen size => print a warning
165 ddraw
->d
.height
= MONITOR_GetHeight(&MONITOR_PrimaryMonitor
);
166 ddraw
->d
.width
= MONITOR_GetWidth(&MONITOR_PrimaryMonitor
);
167 if ((ddraw
->d
.height
!= height
) || (ddraw
->d
.width
!= width
))
168 WARN("You seem to be running in -desktop mode. This may prove dangerous in DGA mode...\n");
169 dgpriv
->fb_addr
= addr
;
170 dgpriv
->fb_memsize
= memsize
;
173 /* just assume the default depth is the DGA depth too */
174 depth
= DefaultDepthOfScreen(X11DRV_GetXScreen());
176 _common_depth_to_pixelformat(depth
, &(ddraw
->d
.directdraw_pixelformat
), &(ddraw
->d
.screen_pixelformat
), NULL
);
178 #ifdef RESTORE_SIGNALS
181 #ifdef HAVE_LIBXXF86DGA2
189 TSXDGAQueryVersion(display
,&major
,&minor
);
190 TRACE("XDGA is version %d.%d\n",major
,minor
);
192 TRACE("Opening the frame buffer.\n");
193 if (!TSXDGAOpenFramebuffer(display
, DefaultScreen(display
))) {
194 ERR("Error opening the frame buffer !!!\n");
195 return DDERR_GENERIC
;
198 /* List all available modes */
199 modes
= TSXDGAQueryModes(display
, DefaultScreen(display
), &num_modes
);
200 dgpriv
->modes
= modes
;
201 dgpriv
->num_modes
= num_modes
;
203 TRACE("Available modes :\n");
204 for (i
= 0; i
< num_modes
; i
++) {
205 if (TRACE_ON(ddraw
)) {
206 DPRINTF(" %d) - %s (FB: %dx%d / VP: %dx%d) - depth %d -",
208 modes
[i
].name
, modes
[i
].imageWidth
, modes
[i
].imageHeight
,
209 modes
[i
].viewportWidth
, modes
[i
].viewportHeight
,
212 #define XX(x) if (modes[i].flags & x) DPRINTF(" "#x" ");
213 XX(XDGAConcurrentAccess
);
214 XX(XDGASolidFillRect
);
216 XX(XDGABlitTransRect
);
221 if ((MONITOR_GetHeight(&MONITOR_PrimaryMonitor
) == modes
[i
].viewportHeight
) &&
222 (MONITOR_GetWidth(&MONITOR_PrimaryMonitor
) == modes
[i
].viewportWidth
) &&
223 (MONITOR_GetDepth(&MONITOR_PrimaryMonitor
) == modes
[i
].depth
)
225 mode_to_use
= modes
[i
].num
;
228 if (mode_to_use
== 0) {
229 ERR("Could not find mode !\n");
232 DPRINTF("Using mode number %d\n", mode_to_use
);
235 /* Initialize the frame buffer */
236 _DGA_Initialize_FrameBuffer(*lplpDD
, mode_to_use
);
237 /* Set the input handling for relative mouse movements */
238 X11DRV_EVENT_SetInputMethod(X11DRV_INPUT_RELATIVE
);
240 #endif /* defined(HAVE_LIBXXF86DGA2) */
244 /* Where do these GUIDs come from? mkuuid.
245 * They exist solely to distinguish between the targets Wine support,
246 * and should be different than any other GUIDs in existence.
248 static GUID DGA_DirectDraw_GUID
= { /* e2dcb020-dc60-11d1-8407-9714f5d50802 */
252 {0x84, 0x07, 0x97, 0x14, 0xf5, 0xd5, 0x08, 0x02}
255 ddraw_driver dga_driver
= {
256 &DGA_DirectDraw_GUID
,
258 "WINE XF86DGA DirectDraw Driver",
264 static void DGA_register(void) __attribute__((constructor
));
265 #else /* defined(__GNUC__) */
266 static void __asm__dummy_dll_init(void) {
267 asm("\t.section .init ,\"ax\"\n"
268 "\tcall DGA_register\n"
271 #endif /* defined(__GNUC__) */
272 static void DGA_register(void) { ddraw_register_driver(&dga_driver
); }