Renamed display to gdi_display where it is used for GDI operations, to
[wine] / dlls / x11drv / x11ddraw.c
1 /*
2  * DirectDraw driver interface
3  *
4  * Copyright 2001 TransGaming Technologies, Inc.
5  */
6
7 #include "config.h"
8
9 #include <string.h>
10
11 #include "ts_xlib.h"
12 #include "x11drv.h"
13 #include "x11ddraw.h"
14 #include "xvidmode.h"
15 #include "dga2.h"
16
17 #include "windef.h"
18 #include "wingdi.h"
19 #include "ddrawi.h"
20 #include "bitmap.h"
21 #include "win.h"
22 #include "debugtools.h"
23
24 DEFAULT_DEBUG_CHANNEL(x11drv);
25
26 extern int dxgrab;
27
28 LPDDRAWI_DDRAWSURFACE_LCL X11DRV_DD_Primary;
29 LPDDRAWI_DDRAWSURFACE_GBL X11DRV_DD_PrimaryGbl;
30 HWND X11DRV_DD_PrimaryWnd;
31 HBITMAP X11DRV_DD_PrimaryDIB;
32 Drawable X11DRV_DD_PrimaryDrawable;
33 ATOM X11DRV_DD_UserClass;
34 BOOL X11DRV_DD_IsDirect;
35
36 static void SetPrimaryDIB(HBITMAP hBmp)
37 {
38   X11DRV_DD_PrimaryDIB = hBmp;
39   if (hBmp) {
40     BITMAPOBJ *bmp;
41     bmp = (BITMAPOBJ *)GDI_GetObjPtr( hBmp, BITMAP_MAGIC );
42     X11DRV_DD_PrimaryDrawable = (Pixmap)bmp->physBitmap;
43     GDI_ReleaseObj( hBmp );
44   } else {
45     X11DRV_DD_PrimaryDrawable = 0;
46   }
47 }
48
49 static void GrabPointer(HWND hWnd)
50 {
51   if (hWnd) {
52     WND *tmpWnd;
53     Window win;
54     /* find the X11 window that ddraw uses */
55     tmpWnd = WIN_FindWndPtr(hWnd);
56     win = X11DRV_WND_GetXWindow(tmpWnd);
57     TRACE("WND: %p win: %ld\n", tmpWnd, win);
58     WIN_ReleaseWndPtr(tmpWnd);
59     if (!win) {
60       TRACE("host off desktop\n");
61       tmpWnd = WIN_FindWndPtr(GetDesktopWindow());
62       win = X11DRV_WND_GetXWindow(tmpWnd);
63       TRACE("Owner WND: %p win: %ld\n", tmpWnd, win);
64       WIN_ReleaseWndPtr(tmpWnd);
65     }
66     TSXGrabPointer(display, win, True, 0, GrabModeAsync, GrabModeAsync, win, None, CurrentTime);
67   }
68   else TSXUngrabPointer(display, CurrentTime);
69 }
70
71 static DWORD PASCAL X11DRV_DDHAL_DestroyDriver(LPDDHAL_DESTROYDRIVERDATA data)
72 {
73   data->ddRVal = DD_OK;
74   return DDHAL_DRIVER_HANDLED;
75 }
76
77 static DWORD PASCAL X11DRV_DDHAL_CreateSurface(LPDDHAL_CREATESURFACEDATA data)
78 {
79   if (data->lpDDSurfaceDesc->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) {
80     X11DRV_DD_Primary = *data->lplpSList;
81     X11DRV_DD_PrimaryWnd = (HWND)X11DRV_DD_Primary->lpSurfMore->lpDDRAWReserved;
82     X11DRV_DD_PrimaryGbl = X11DRV_DD_Primary->lpGbl;
83     SetPrimaryDIB(GET_LPDDRAWSURFACE_GBL_MORE(X11DRV_DD_PrimaryGbl)->hKernelSurface);
84     X11DRV_DD_UserClass = GlobalFindAtomA("WINE_DDRAW");
85     if (dxgrab) GrabPointer(X11DRV_DD_PrimaryWnd);
86   }
87   data->ddRVal = DD_OK;
88   return DDHAL_DRIVER_NOTHANDLED;
89 }
90
91 static DWORD PASCAL X11DRV_DDHAL_CreatePalette(LPDDHAL_CREATEPALETTEDATA data)
92 {
93   FIXME("stub\n");
94   /* only makes sense to do anything if the X server is running at 8bpp,
95    * which few people do nowadays */
96   data->ddRVal = DD_OK;
97   return DDHAL_DRIVER_HANDLED;
98 }
99
100 static DDHAL_DDCALLBACKS hal_ddcallbacks = {
101   sizeof(DDHAL_DDCALLBACKS),
102   0x3ff, /* all callbacks are 32-bit */
103   X11DRV_DDHAL_DestroyDriver,
104   X11DRV_DDHAL_CreateSurface,
105   NULL, /* SetColorKey */
106   NULL, /* SetMode */
107   NULL, /* WaitForVerticalBlank */
108   NULL, /* CanCreateSurface */
109   X11DRV_DDHAL_CreatePalette,
110   NULL, /* GetScanLine */
111   NULL, /* SetExclusiveMode */
112   NULL  /* FlipToGDISurface */
113 };
114
115 static DWORD PASCAL X11DRV_DDHAL_DestroySurface(LPDDHAL_DESTROYSURFACEDATA data)
116 {
117   if (data->lpDDSurface == X11DRV_DD_Primary) {
118     X11DRV_DD_Primary = NULL;
119     X11DRV_DD_PrimaryWnd = 0;
120     X11DRV_DD_PrimaryGbl = NULL;
121     SetPrimaryDIB(0);
122     X11DRV_DD_UserClass = 0;
123     if (dxgrab) GrabPointer(0);
124   }
125   data->ddRVal = DD_OK;
126   return DDHAL_DRIVER_HANDLED;
127 }
128
129 static DWORD PASCAL X11DRV_DDHAL_SetPalette(LPDDHAL_SETPALETTEDATA data)
130 {
131   Colormap pal = data->lpDDPalette->u1.dwReserved1;
132   if (pal) {
133     if (data->lpDDSurface == X11DRV_DD_Primary) {
134       FIXME("stub\n");
135       /* we should probably find the ddraw window (maybe data->lpDD->lpExclusiveOwner->hWnd),
136        * and attach the palette to it */
137     }
138   }
139   data->ddRVal = DD_OK;
140   return DDHAL_DRIVER_HANDLED;
141 }
142
143 static DDHAL_DDSURFACECALLBACKS hal_ddsurfcallbacks = {
144   sizeof(DDHAL_DDSURFACECALLBACKS),
145   0x3fff, /* all callbacks are 32-bit */
146   X11DRV_DDHAL_DestroySurface,
147   NULL, /* Flip */
148   NULL, /* SetClipList */
149   NULL, /* Lock */
150   NULL, /* Unlock */
151   NULL, /* Blt */
152   NULL, /* SetColorKey */
153   NULL, /* AddAttachedSurface */
154   NULL, /* GetBltStatus */
155   NULL, /* GetFlipStatus */
156   NULL, /* UpdateOverlay */
157   NULL, /* SetOverlayPosition */
158   NULL, /* reserved4 */
159   X11DRV_DDHAL_SetPalette
160 };
161
162 static DWORD PASCAL X11DRV_DDHAL_DestroyPalette(LPDDHAL_DESTROYPALETTEDATA data)
163 {
164   Colormap pal = data->lpDDPalette->u1.dwReserved1;
165   if (pal) TSXFreeColormap(gdi_display, pal);
166   data->ddRVal = DD_OK;
167   return DDHAL_DRIVER_HANDLED;
168 }
169
170 static DWORD PASCAL X11DRV_DDHAL_SetPaletteEntries(LPDDHAL_SETENTRIESDATA data)
171 {
172   X11DRV_DDHAL_SetPalEntries(data->lpDDPalette->u1.dwReserved1,
173                              data->dwBase, data->dwNumEntries,
174                              data->lpEntries);
175   data->ddRVal = DD_OK;
176   return DDHAL_DRIVER_HANDLED;
177 }
178
179 static DDHAL_DDPALETTECALLBACKS hal_ddpalcallbacks = {
180   sizeof(DDHAL_DDPALETTECALLBACKS),
181   0x3, /* all callbacks are 32-bit */
182   X11DRV_DDHAL_DestroyPalette,
183   X11DRV_DDHAL_SetPaletteEntries
184 };
185
186 static X11DEVICE x11device = {
187   NULL
188 };
189
190 static DWORD PASCAL X11DRV_DDHAL_GetDriverInfo(LPDDHAL_GETDRIVERINFODATA data)
191 {
192   LPX11DRIVERINFO info = x11device.lpInfo;
193   while (info) {
194     if (IsEqualGUID(&data->guidInfo, info->lpGuid)) {
195       DWORD dwSize = info->dwSize;
196       data->dwActualSize = dwSize;
197       if (data->dwExpectedSize < dwSize) dwSize = data->dwExpectedSize;
198       memcpy(data->lpvData, info->lpvData, dwSize);
199       data->ddRVal = DD_OK;
200       return DDHAL_DRIVER_HANDLED;
201     }
202     info = info->lpNext;
203   }
204   data->ddRVal = DDERR_CURRENTLYNOTAVAIL;
205   return DDHAL_DRIVER_HANDLED;
206 }
207
208 static DDHALINFO hal_info = {
209   sizeof(DDHALINFO),
210   &hal_ddcallbacks,
211   &hal_ddsurfcallbacks,
212   &hal_ddpalcallbacks,
213   {     /* vmiData */
214    0     /* fpPrimary */
215   },
216   {     /* ddCaps (only stuff the HAL implements here) */
217    sizeof(DDCORECAPS),                                                  /* dwSize */
218    DDCAPS_GDI | DDCAPS_PALETTE,                                         /* dwCaps */
219    DDCAPS2_CERTIFIED | DDCAPS2_NONLOCALVIDMEM | DDCAPS2_NOPAGELOCKREQUIRED |
220    DDCAPS2_WIDESURFACES | DDCAPS2_PRIMARYGAMMA | DDCAPS2_FLIPNOVSYNC,   /* dwCaps2 */
221    0,                                                                   /* dwCKeyCaps */
222    0,                                                                   /* dwFXCaps */
223    0,                                                                   /* dwFXAlphaCaps */
224    DDPCAPS_8BIT | DDPCAPS_PRIMARYSURFACE,                               /* dwPalCaps */
225    0,                                                                   /* dwSVCaps */
226    0,                                                                   /* dwAlphaBltConstBitDepths */
227    0,                                                                   /* dwAlphaBltPixelBitDepths */
228    0,                                                                   /* dwAlphaBltSurfaceBitDepths */
229    0,                                                                   /* dwAlphaOverlayBltConstBitDepths */
230    0,                                                                   /* dwAlphaOverlayBltPixelBitDepths */
231    0,                                                                   /* dwAlphaOverlayBltSurfaceBitDepths */
232    0,                                                                   /* dwZBufferBitDepths */
233    16*1024*1024,                                                        /* dwVidMemTotal */
234    16*1024*1024,                                                        /* dwVidMemFree */
235    0,                                                                   /* dwMaxVisibleOverlays */
236    0,                                                                   /* dwCurrVisibleOverlays */
237    0,                                                                   /* dwNumFourCCCodes */
238    0,                                                                   /* dwAlignBoundarySrc */
239    0,                                                                   /* dwAlignSizeSrc */
240    0,                                                                   /* dwAlignBoundaryDest */
241    0,                                                                   /* dwAlignSizeDest */
242    0,                                                                   /* dwAlignStrideAlign */
243    {0},                                                                 /* dwRops */
244    {                                                                    /* ddsCaps */
245     DDSCAPS_BACKBUFFER | DDSCAPS_FLIP | DDSCAPS_FRONTBUFFER |
246     DDSCAPS_OFFSCREENPLAIN | DDSCAPS_PALETTE | DDSCAPS_PRIMARYSURFACE |
247     DDSCAPS_SYSTEMMEMORY | DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY |
248     DDSCAPS_VISIBLE | DDSCAPS_LOCALVIDMEM | DDSCAPS_NONLOCALVIDMEM      /* dwCaps */
249    },
250    0,                                                                   /* dwMinOverlayStretch */
251    0,                                                                   /* dwMaxOverlayStretch */
252    0,                                                                   /* dwMinLiveVideoStretch */
253    0,                                                                   /* dwMaxLiveVideoStretch */
254    0,                                                                   /* dwMinHwCodecStretch */
255    0,                                                                   /* dwMaxHwCodecStretch */
256    0,                                                                   /* dwReserved1 */
257    0,                                                                   /* dwReserved2 */
258    0,                                                                   /* dwReserved2 */
259    0,                                                                   /* dwSVBCaps */
260    0,                                                                   /* dwSVBCKeyCaps */
261    0,                                                                   /* dwSVBFXCaps */
262    {0},                                                                 /* dwSVBRops */
263    0,                                                                   /* dwVSBCaps */
264    0,                                                                   /* dwVSBCKeyCaps */
265    0,                                                                   /* dwVSBFXCaps */
266    {0},                                                                 /* dwVSBRops */
267    0,                                                                   /* dwSSBCaps */
268    0,                                                                   /* dwSSBCKeyCaps */
269    0,                                                                   /* dwSSBFXCaps */
270    {0},                                                                 /* dwSSBRops */
271    0,                                                                   /* dwMaxVideoPorts */
272    0,                                                                   /* dwCurrVideoPorts */
273    0                                                                    /* dwSVBCaps */
274   },
275   0,    /* dwMonitorFrequency */
276   X11DRV_DDHAL_GetDriverInfo,
277   0,    /* dwModeIndex */
278   NULL, /* lpdwFourCC */
279   0,    /* dwNumModes */
280   NULL, /* lpModeInfo */
281   DDHALINFO_ISPRIMARYDISPLAY | DDHALINFO_MODEXILLEGAL | DDHALINFO_GETDRIVERINFOSET, /* dwFlags */
282   &x11device,
283   0,    /* hInstance */
284   0,    /* lpD3DGlobalDriverData */
285   0,    /* lpD3DHALCallbacks */
286   NULL  /* lpDDExeBufCallbacks */
287 };
288
289 static LPDDHALDDRAWFNS ddraw_fns;
290 static DWORD ddraw_ver;
291
292 static void X11DRV_DDHAL_SetInfo(void)
293 {
294   (ddraw_fns->lpSetInfo)(&hal_info, FALSE);
295 }
296
297 INT X11DRV_DCICommand(INT cbInput, LPVOID lpInData, LPVOID lpOutData)
298 {
299   LPDCICMD lpCmd = (LPDCICMD)lpInData;
300
301   TRACE("(%d,(%ld,%ld,%ld),%p)\n", cbInput, lpCmd->dwCommand,
302         lpCmd->dwParam1, lpCmd->dwParam2, lpOutData);
303
304   switch (lpCmd->dwCommand) {
305   case DDNEWCALLBACKFNS:
306     ddraw_fns = (LPDDHALDDRAWFNS)lpCmd->dwParam1;
307     return TRUE;
308   case DDVERSIONINFO:
309     {
310       LPDDVERSIONDATA lpVer = (LPDDVERSIONDATA)lpOutData;
311       ddraw_ver = lpCmd->dwParam1;
312       if (!lpVer) break;
313       /* well, whatever... the DDK says so */
314       lpVer->dwHALVersion = DD_RUNTIME_VERSION;
315     }
316     return TRUE;
317   case DDGET32BITDRIVERNAME:
318     {
319       LPDD32BITDRIVERDATA lpData = (LPDD32BITDRIVERDATA)lpOutData;
320       /* here, we could ask ddraw to load a separate DLL, that
321        * would contain the 32-bit ddraw HAL */
322       strcpy(lpData->szName,"x11drv");
323       /* the entry point named here should initialize our hal_info
324        * with 32-bit entry points (ignored for now) */
325       strcpy(lpData->szEntryPoint,"DriverInit");
326       lpData->dwContext = 0;
327     }
328     return TRUE;
329   case DDCREATEDRIVEROBJECT:
330     {
331       LPDWORD lpInstance = (LPDWORD)lpOutData;
332
333       /* FIXME: get x11drv's hInstance */
334 #ifdef HAVE_LIBXXF86DGA2
335       if (!X11DRV_XF86DGA2_CreateDriver(&hal_info))
336 #endif
337       {
338 #ifdef HAVE_LIBXXF86VM
339         X11DRV_XF86VM_CreateDriver(&hal_info);
340 #endif
341       }
342 #ifdef HAVE_OPENGL
343       /*X11DRV_GLX_CreateDriver(&hal_info);*/
344 #endif
345
346       (ddraw_fns->lpSetInfo)(&hal_info, FALSE);
347       *lpInstance = hal_info.hInstance;
348     }
349     return TRUE;
350   }
351   return 0;
352 }
353
354 void X11DRV_DDHAL_SwitchMode(DWORD dwModeIndex, LPVOID fb_addr, LPVIDMEM fb_mem)
355 {
356   LPDDHALMODEINFO info = &hal_info.lpModeInfo[dwModeIndex];
357
358   hal_info.dwModeIndex        = dwModeIndex;
359   hal_info.dwMonitorFrequency = info->wRefreshRate;
360   hal_info.vmiData.fpPrimary  = (FLATPTR)fb_addr;
361   hal_info.vmiData.dwDisplayWidth  = info->dwWidth;
362   hal_info.vmiData.dwDisplayHeight = info->dwHeight;
363   hal_info.vmiData.lDisplayPitch   = info->lPitch;
364   hal_info.vmiData.ddpfDisplay.dwSize = info->dwBPP ? sizeof(hal_info.vmiData.ddpfDisplay) : 0;
365   hal_info.vmiData.ddpfDisplay.dwFlags = (info->wFlags & DDMODEINFO_PALETTIZED) ? DDPF_PALETTEINDEXED8 : 0;
366   hal_info.vmiData.ddpfDisplay.u1.dwRGBBitCount = (info->dwBPP > 24) ? 24 : info->dwBPP;
367   hal_info.vmiData.ddpfDisplay.u2.dwRBitMask = info->dwRBitMask;
368   hal_info.vmiData.ddpfDisplay.u3.dwGBitMask = info->dwGBitMask;
369   hal_info.vmiData.ddpfDisplay.u4.dwBBitMask = info->dwBBitMask;
370   hal_info.vmiData.dwNumHeaps = fb_mem ? 1 : 0;
371   hal_info.vmiData.pvmList = fb_mem;
372
373   X11DRV_DDHAL_SetInfo();
374 }
375
376 void X11DRV_DDHAL_SetPalEntries(Colormap pal, DWORD dwBase, DWORD dwNumEntries,
377                                 LPPALETTEENTRY lpEntries)
378 {
379   XColor c;
380   int n;
381
382   if (pal) {
383     c.flags = DoRed|DoGreen|DoBlue;
384     c.pixel = dwBase;
385     for (n=0; n<dwNumEntries; n++,c.pixel++) {
386       c.red   = lpEntries[n].peRed   << 8;
387       c.green = lpEntries[n].peGreen << 8;
388       c.blue  = lpEntries[n].peBlue  << 8;
389       TSXStoreColor(gdi_display, pal, &c);
390     }
391     TSXFlush(gdi_display); /* update display immediately */
392   }
393 }