Removed a few dependencies on kernel32 functions.
[wine] / dlls / ddraw / dga2.c
1 /*              DirectDraw using DGA2
2  *
3  * Based (well, plagiarized :-) ) on Marcus' dga.c
4  */
5
6 #include "config.h"
7 #include "winerror.h"
8
9 #include <unistd.h>
10 #include <assert.h>
11 #ifdef HAVE_SYS_SIGNAL_H
12 # include <sys/signal.h>
13 #endif
14 #include <fcntl.h>
15 #include <string.h>
16 #include <stdio.h>
17
18 #include "gdi.h"
19 #include "heap.h"
20 #include "wine/exception.h"
21 #include "ddraw.h"
22 #include "d3d.h"
23 #include "debugtools.h"
24 #include "options.h"
25
26 #include "dga2_private.h"
27
28 DEFAULT_DEBUG_CHANNEL(ddraw);
29
30 static inline BOOL get_option( const char *name, BOOL def ) {
31     return PROFILE_GetWineIniBool( "x11drv", name, def );
32 }
33
34 static BYTE
35 DDRAW_DGA2_Available(void)
36 {
37     int evbase, evret, majver, minver;
38     static BYTE return_value = 0xFF;
39
40     /* This prevents from probing X times for DGA */
41     if (return_value != 0xFF)
42         return return_value;
43
44     if (!get_option( "UseDGA", 1 )) {
45         TRACE("UseDGA disabled.\n");
46         return_value = 0;
47         return 0;
48     }
49
50     /* First, query the extenstion and its version */
51     if (!TSXF86DGAQueryExtension(display,&evbase,&evret)) {
52         TRACE("DGA extension not detected.\n");
53         return_value = 0;
54         return 0;
55     }
56
57     if (!TSXF86DGAQueryVersion(display,&majver,&minver)) {
58         TRACE("DGA version not detected.\n");
59         return_value = 0;
60         return 0;
61     }
62
63     if (majver >= 2) {
64         /* We have DGA 2.0 available ! */
65         if (TSXDGAOpenFramebuffer(display, DefaultScreen(display))) {
66             TSXDGACloseFramebuffer(display, DefaultScreen(display));
67             return_value = 2;
68         } else
69             return_value = 0;
70         return return_value;
71     }
72     
73     return 0;
74 }
75
76 HRESULT 
77 DGA2_Create( LPDIRECTDRAW *lplpDD ) {
78     IDirectDrawImpl*            ddraw;
79     dga2_dd_private*    dgpriv;
80     int  major,minor;
81     int  dga_version;
82     XDGAMode *modes;
83     int i, num_modes;
84     int mode_to_use = 0;
85
86     /* Get DGA availability / version */
87     dga_version = DDRAW_DGA2_Available();
88     if (dga_version == 0)
89         return DDERR_GENERIC;
90
91     /* If we were just testing ... return OK */
92     if (lplpDD == NULL)
93         return DD_OK;
94
95     ddraw = (IDirectDrawImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawImpl));
96     *lplpDD = (LPDIRECTDRAW)ddraw;
97     ddraw->ref = 1;
98     ICOM_VTBL(ddraw) = &dga2_ddvt;
99
100     ddraw->d = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(*(ddraw->d)));
101     ddraw->d->ref = 1;
102     ddraw->d->private = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(dga2_dd_private));
103
104     dgpriv = (dga2_dd_private*)ddraw->d->private;
105     
106     TSXDGAQueryVersion(display,&major,&minor);
107     TRACE("XDGA is version %d.%d\n",major,minor);
108     
109     TRACE("Opening the frame buffer.\n");
110     if (!TSXDGAOpenFramebuffer(display, DefaultScreen(display))) {
111       ERR("Error opening the frame buffer !!!\n");
112       return DDERR_GENERIC;
113     }
114
115     /* List all available modes */
116     modes = TSXDGAQueryModes(display, DefaultScreen(display), &num_modes);
117     dgpriv->modes       = modes;
118     dgpriv->num_modes   = num_modes;
119     
120     TRACE("Available modes :\n");
121     for (i = 0; i < num_modes; i++) {
122       if (TRACE_ON(ddraw)) {
123         DPRINTF("   %d) - %s (FB: %dx%d / VP: %dx%d) - depth %d -",
124                 modes[i].num,
125                 modes[i].name, modes[i].imageWidth, modes[i].imageHeight,
126                 modes[i].viewportWidth, modes[i].viewportHeight,
127                 modes[i].depth
128                 );
129 #define XX(x) if (modes[i].flags & x) DPRINTF(" "#x" ");
130         XX(XDGAConcurrentAccess);
131         XX(XDGASolidFillRect);
132         XX(XDGABlitRect);
133         XX(XDGABlitTransRect);
134         XX(XDGAPixmap);
135 #undef XX
136         DPRINTF("\n");
137       }
138       if ((GetSystemMetrics(SM_CYSCREEN) == modes[i].viewportHeight) &&
139           (GetSystemMetrics(SM_CXSCREEN) == modes[i].viewportWidth) &&
140           (X11DRV_GetDepth() == modes[i].depth)
141           ) {
142         mode_to_use = modes[i].num;
143       }
144     }
145     if (mode_to_use == 0) {
146       ERR("Could not find mode !\n");
147       mode_to_use = 1;
148     } else {
149       TRACE("Using mode number %d\n", mode_to_use);
150     }
151
152     dgpriv->DGA.InstallColormap = TSXDGAInstallColormap;
153     
154     /* Initialize the frame buffer */
155     _DGA2_Initialize_FrameBuffer(ddraw, mode_to_use);
156
157     /* Register frame buffer with the kernel, it is a potential DIB section */
158     VirtualAlloc(dgpriv->DGA.fb_addr, dgpriv->DGA.fb_memsize, MEM_RESERVE|MEM_SYSTEM, PAGE_READWRITE);
159     
160     /* Set the input handling for relative mouse movements */
161     X11DRV_EVENT_SetInputMethod(X11DRV_INPUT_RELATIVE);
162     
163     return DD_OK;
164 }
165
166 /* Where do these GUIDs come from?  mkuuid.
167  * They exist solely to distinguish between the targets Wine support,
168  * and should be different than any other GUIDs in existence.
169  */
170 static GUID DGA2_DirectDraw_GUID = { /* e2dcb020-dc60-11d1-8407-9714f5d50803 */
171     0xe2dcb020,
172     0xdc60,
173     0x11d1,
174     {0x84, 0x07, 0x97, 0x14, 0xf5, 0xd5, 0x08, 0x03}
175 };
176
177 ddraw_driver dga2_driver = {
178     &DGA2_DirectDraw_GUID,
179     "display",
180     "WINE XF86DGA2 DirectDraw Driver",
181     150,
182     DGA2_Create
183 }; 
184
185 DECL_GLOBAL_CONSTRUCTOR(DGA2_register) { ddraw_register_driver(&dga2_driver); }