Correct some cut & paste typos.
[wine/multimedia.git] / dlls / ddraw / dga.c
blob4acb9bd17b15ef5d30140734fb99595db1e4f846
1 /* DirectDraw using DGA
3 * Copyright 1997-2000 Marcus Meissner
4 * Copyright 1998-2000 Lionel Ulmer (most of Direct3D stuff)
5 */
6 /* XF86DGA:
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
10 * is running.
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.
17 #include "config.h"
18 #include "winerror.h"
20 #include <unistd.h>
21 #include <assert.h>
22 #ifdef HAVE_SYS_SIGNAL_H
23 # include <sys/signal.h>
24 #endif
25 #include <fcntl.h>
26 #include <string.h>
27 #include <stdio.h>
29 #include "heap.h"
30 #include "wine/exception.h"
31 #include "ddraw.h"
32 #include "d3d.h"
33 #include "debugtools.h"
34 #include "options.h"
36 #include "dga_private.h"
38 #define RESTORE__SIGNALS
40 DEFAULT_DEBUG_CHANNEL(ddraw);
42 #ifdef HAVE_LIBXXF86VM
43 XF86VidModeModeInfo *orig_mode = NULL;
44 #endif
46 static inline BOOL get_option( const char *name, BOOL def ) {
47 return PROFILE_GetWineIniBool( "x11drv", name, def );
50 static BYTE
51 DDRAW_DGA_Available(void)
53 int fd, evbase, evret, majver, minver;
54 static BYTE return_value = 0xFF;
56 /* This prevents from probing X times for DGA */
57 if (return_value != 0xFF)
58 return return_value;
60 if (!get_option( "UseDGA", 1 )) {
61 TRACE("UseDGA disabled.\n");
62 return_value = 0;
63 return 0;
66 /* First, query the extenstion and its version */
67 if (!TSXF86DGAQueryExtension(display,&evbase,&evret)) {
68 TRACE("DGA extension not detected.\n");
69 return_value = 0;
70 return 0;
73 if (!TSXF86DGAQueryVersion(display,&majver,&minver)) {
74 TRACE("DGA version not detected.\n");
75 return_value = 0;
76 return 0;
79 /* You don't have to be root to use DGA extensions. Simply having access
80 * to /dev/mem will do the trick
81 * This can be achieved by adding the user to the "kmem" group on
82 * Debian 2.x systems, don't know about
83 * others. --stephenc
85 if ((fd = open("/dev/mem", O_RDWR)) != -1)
86 close(fd);
88 if (fd != -1)
89 return_value = 1;
90 else {
91 TRACE("You have no access to /dev/mem\n");
92 return_value = 0;
94 return return_value;
97 HRESULT
98 DGA_Create( LPDIRECTDRAW *lplpDD ) {
99 IDirectDrawImpl* ddraw;
100 dga_dd_private* dgpriv;
101 int memsize,banksize,major,minor,flags;
102 char *addr;
103 int depth;
104 int dga_version;
105 int width, height;
107 /* Get DGA availability / version */
108 dga_version = DDRAW_DGA_Available();
109 if (dga_version == 0)
110 return DDERR_GENERIC;
112 /* If we were just testing ... return OK */
113 if (lplpDD == NULL)
114 return DD_OK;
116 ddraw = (IDirectDrawImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawImpl));
117 *lplpDD = (LPDIRECTDRAW)ddraw;
118 ddraw->ref = 1;
119 ICOM_VTBL(ddraw) = &dga_ddvt;
120 ddraw->d = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(*(ddraw->d)));
121 ddraw->d->ref = 1;
122 ddraw->d->private = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(dga_dd_private));
123 dgpriv = (dga_dd_private*)ddraw->d->private;
125 TSXF86DGAQueryVersion(display,&major,&minor);
126 TRACE("XF86DGA is version %d.%d\n",major,minor);
128 TSXF86DGAQueryDirectVideo(display,DefaultScreen(display),&flags);
129 if (!(flags & XF86DGADirectPresent)) {
130 /* On some boards, DGA extension is present but does not support DirectVideo */
131 MESSAGE("direct video is NOT PRESENT.\n");
132 return DDERR_GENERIC;
134 TSXF86DGAGetVideo(display,DefaultScreen(display),&addr,&width,&banksize,&memsize);
135 dgpriv->fb_width = width;
136 TSXF86DGAGetViewPortSize(display,DefaultScreen(display),&width,&height);
137 TSXF86DGASetViewPort(display,DefaultScreen(display),0,0);
138 dgpriv->fb_height = height;
139 TRACE("video framebuffer: begin %p, width %d,banksize %d,memsize %d\n",
140 addr,width,banksize,memsize
142 TRACE("viewport height: %d\n",height);
143 /* Get the screen dimensions as seen by Wine.
144 * In that case, it may be better to ignore the -desktop mode and
145 * return the real screen size => print a warning
147 ddraw->d->height = GetSystemMetrics(SM_CYSCREEN);
148 ddraw->d->width = GetSystemMetrics(SM_CXSCREEN);
149 if ((ddraw->d->height != height) || (ddraw->d->width != width))
150 WARN("You seem to be running in -desktop mode. This may prove dangerous in DGA mode...\n");
151 dgpriv->fb_addr = addr;
152 dgpriv->fb_memsize = memsize;
153 dgpriv->vpmask = 0;
155 /* Register frame buffer with the kernel, it is a potential DIB section */
156 VirtualAlloc(dgpriv->fb_addr, dgpriv->fb_memsize, MEM_RESERVE|MEM_SYSTEM, PAGE_READWRITE);
158 /* The cast is because DGA2's install colormap does not return a value whereas
159 DGA1 version does */
160 dgpriv->InstallColormap = (void (*)(Display *, int, Colormap)) TSXF86DGAInstallColormap;
162 /* just assume the default depth is the DGA depth too */
163 depth = DefaultDepthOfScreen(X11DRV_GetXScreen());
165 _common_depth_to_pixelformat(depth, (IDirectDraw*) ddraw);
167 #ifdef RESTORE_SIGNALS
168 SIGNAL_Init();
169 #endif
171 return DD_OK;
174 /* Where do these GUIDs come from? mkuuid.
175 * They exist solely to distinguish between the targets Wine support,
176 * and should be different than any other GUIDs in existence.
178 static GUID DGA_DirectDraw_GUID = { /* e2dcb020-dc60-11d1-8407-9714f5d50802 */
179 0xe2dcb020,
180 0xdc60,
181 0x11d1,
182 {0x84, 0x07, 0x97, 0x14, 0xf5, 0xd5, 0x08, 0x02}
185 ddraw_driver dga_driver = {
186 &DGA_DirectDraw_GUID,
187 "display",
188 "WINE XF86DGA DirectDraw Driver",
189 100,
190 DGA_Create
193 DECL_GLOBAL_CONSTRUCTOR(DGA_register) { ddraw_register_driver(&dga_driver); }