int directdraw_uninit(void) { if(!video_window) return 0; if(!lpDDS) return 0; KillTimer(video_window, 131); if(lpDDS_secondary) IDirectDrawSurface2_Release(lpDDS_secondary); if(lpDDS) IDirectDrawSurface2_Release(lpDDS); if(surface_osd) IDirectDrawSurface2_Release(surface_osd); if(lpDD) IDirectDraw2_RestoreDisplayMode(lpDD); if(lpDD) IDirectDraw2_SetCooperativeLevel(lpDD, video_window, DDSCL_NORMAL); if(lpDD) IDirectDraw2_Release(lpDD); if(video_window) DestroyWindow(video_window); if(library) FreeLibrary(library); library = 0; lpDD = 0; lpDDS = 0; lpDDS_secondary = 0; surface_osd = 0; video_window = 0; return 1; }
/* wnd_set_video_mode: * Called by window thread to set a gfx mode; this is needed because DirectDraw can only * change the mode in the thread that handles the window. */ static int wnd_set_video_mode(void) { HRESULT hr; HWND allegro_wnd = win_get_window(); /* set the cooperative level to allow fullscreen access */ hr = IDirectDraw2_SetCooperativeLevel(directdraw, allegro_wnd, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN); if (FAILED(hr)) { _TRACE(PREFIX_E "SetCooperativeLevel() failed (%x)\n", hr); return -1; } /* switch to fullscreen mode */ hr = IDirectDraw2_SetDisplayMode(directdraw, _wnd_width, _wnd_height, _wnd_depth, _wnd_refresh_rate, _wnd_flags); if (FAILED(hr)) { _TRACE(PREFIX_E "SetDisplayMode(%u, %u, %u, %u, %u) failed (%x)\n", _wnd_width, _wnd_height, _wnd_depth, _wnd_refresh_rate, _wnd_flags, hr); return -1; } return 0; }
static void DDDestroySurface(directx_priv *priv) { int i; if (priv->lpddp != NULL) { IDirectDrawPalette_Release(priv->lpddp); priv->lpddp = NULL; } for (i = 0; i < GGI_DISPLAY_DIRECTX_FRAMES; ++i) { if (priv->lpbdds[i] != NULL) { IDirectDrawSurface_Release(priv->lpbdds[i]); priv->lpbdds[i] = NULL; } } if (priv->lppdds != NULL) { IDirectDrawSurface_Release(priv->lppdds); priv->lppdds = NULL; } if (priv->fullscreen) { IDirectDraw2_RestoreDisplayMode(priv->lpddext); IDirectDraw2_SetCooperativeLevel(priv->lpddext, priv->hWnd, DDSCL_NORMAL); } }
static Bool winAllocateFBShadowDD (ScreenPtr pScreen) { winScreenPriv(pScreen); winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; HRESULT ddrval = DD_OK; DDSURFACEDESC ddsd; DDSURFACEDESC *pddsdShadow = NULL; #if CYGDEBUG winDebug ("winAllocateFBShadowDD\n"); #endif /* Create a clipper */ ddrval = (*g_fpDirectDrawCreateClipper) (0, &pScreenPriv->pddcPrimary, NULL); if (FAILED (ddrval)) { ErrorF ("winAllocateFBShadowDD - Could not create clipper: %08x\n", (unsigned int) ddrval); return FALSE; } #if CYGDEBUG winDebug ("winAllocateFBShadowDD - Created a clipper\n"); #endif /* Get a device context for the screen */ pScreenPriv->hdcScreen = GetDC (pScreenPriv->hwndScreen); /* Attach the clipper to our display window */ ddrval = IDirectDrawClipper_SetHWnd (pScreenPriv->pddcPrimary, 0, pScreenPriv->hwndScreen); if (FAILED (ddrval)) { ErrorF ("winAllocateFBShadowDD - Clipper not attached to " "window: %08x\n", (unsigned int) ddrval); return FALSE; } #if CYGDEBUG winDebug ("winAllocateFBShadowDD - Attached clipper to window\n"); #endif /* Create a DirectDraw object, store the address at lpdd */ ddrval = (*g_fpDirectDrawCreate) (NULL, &pScreenPriv->pdd, NULL); if (FAILED (ddrval)) { ErrorF ("winAllocateFBShadowDD - Could not start DirectDraw: %08x\n", (unsigned int) ddrval); return FALSE; } #if CYGDEBUG winDebug ("winAllocateFBShadowDD () - Created and initialized DD\n"); #endif /* Get a DirectDraw2 interface pointer */ ddrval = IDirectDraw_QueryInterface (pScreenPriv->pdd, &IID_IDirectDraw2, (LPVOID*) &pScreenPriv->pdd2); if (FAILED (ddrval)) { ErrorF ("winAllocateFBShadowDD - Failed DD2 query: %08x\n", (unsigned int) ddrval); return FALSE; } /* Are we full screen? */ if (pScreenInfo->fFullScreen) { DDSURFACEDESC ddsdCurrent; DWORD dwRefreshRateCurrent = 0; HDC hdc = NULL; /* Set the cooperative level to full screen */ ddrval = IDirectDraw2_SetCooperativeLevel (pScreenPriv->pdd2, pScreenPriv->hwndScreen, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN); if (FAILED (ddrval)) { ErrorF ("winAllocateFBShadowDD - Could not set " "cooperative level: %08x\n", (unsigned int) ddrval); return FALSE; } /* * We only need to get the current refresh rate for comparison * if a refresh rate has been passed on the command line. */ if (pScreenInfo->dwRefreshRate != 0) { ZeroMemory (&ddsdCurrent, sizeof (ddsdCurrent)); ddsdCurrent.dwSize = sizeof (ddsdCurrent); /* Get information about current display settings */ ddrval = IDirectDraw2_GetDisplayMode (pScreenPriv->pdd2, &ddsdCurrent); if (FAILED (ddrval)) { ErrorF ("winAllocateFBShadowDD - Could not get current " "refresh rate: %08x. Continuing.\n", (unsigned int) ddrval); dwRefreshRateCurrent = 0; } else { /* Grab the current refresh rate */ dwRefreshRateCurrent = ddsdCurrent.u2.dwRefreshRate; } } /* Clean up the refresh rate */ if (dwRefreshRateCurrent == pScreenInfo->dwRefreshRate) { /* * Refresh rate is non-specified or equal to current. */ pScreenInfo->dwRefreshRate = 0; } /* Grab a device context for the screen */ hdc = GetDC (NULL); if (hdc == NULL) { ErrorF ("winAllocateFBShadowDD - GetDC () failed\n"); return FALSE; } /* Only change the video mode when different than current mode */ if (!pScreenInfo->fMultipleMonitors && (pScreenInfo->dwWidth != GetSystemMetrics (SM_CXSCREEN) || pScreenInfo->dwHeight != GetSystemMetrics (SM_CYSCREEN) || pScreenInfo->dwBPP != GetDeviceCaps (hdc, BITSPIXEL) || pScreenInfo->dwRefreshRate != 0)) { ErrorF ("winAllocateFBShadowDD - Changing video mode\n"); /* Change the video mode to the mode requested, and use the driver default refresh rate on failure */ ddrval = IDirectDraw2_SetDisplayMode (pScreenPriv->pdd2, pScreenInfo->dwWidth, pScreenInfo->dwHeight, pScreenInfo->dwBPP, pScreenInfo->dwRefreshRate, 0); if (FAILED (ddrval)) { ErrorF ("winAllocateFBShadowDD - Could not set "\ "full screen display mode: %08x\n", (unsigned int) ddrval); ErrorF ("winAllocateFBShadowDD - Using default driver refresh rate\n"); ddrval = IDirectDraw2_SetDisplayMode (pScreenPriv->pdd2, pScreenInfo->dwWidth, pScreenInfo->dwHeight, pScreenInfo->dwBPP, 0, 0); if (FAILED(ddrval)) { ErrorF ("winAllocateFBShadowDD - Could not set default refresh rate " "full screen display mode: %08x\n", (unsigned int) ddrval); return FALSE; } } } else { ErrorF ("winAllocateFBShadowDD - Not changing video mode\n"); } /* Release our DC */ ReleaseDC (NULL, hdc); hdc = NULL; } else { /* Set the cooperative level for windowed mode */ ddrval = IDirectDraw2_SetCooperativeLevel (pScreenPriv->pdd2, pScreenPriv->hwndScreen, DDSCL_NORMAL); if (FAILED (ddrval)) { ErrorF ("winAllocateFBShadowDD - Could not set "\ "cooperative level: %08x\n", (unsigned int) ddrval); return FALSE; } } /* Create the primary surface */ if (!winCreatePrimarySurfaceShadowDD (pScreen)) { ErrorF ("winAllocateFBShadowDD - winCreatePrimarySurfaceShadowDD " "failed\n"); return FALSE; } /* Describe the shadow surface to be created */ /* NOTE: Do not use a DDSCAPS_VIDEOMEMORY surface, * as drawing, locking, and unlocking take forever * with video memory surfaces. In addition, * video memory is a somewhat scarce resource, * so you shouldn't be allocating video memory when * you have the option of using system memory instead. */ ZeroMemory (&ddsd, sizeof (ddsd)); ddsd.dwSize = sizeof (ddsd); ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH; ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY; ddsd.dwHeight = pScreenInfo->dwHeight; ddsd.dwWidth = pScreenInfo->dwWidth; /* Create the shadow surface */ ddrval = IDirectDraw2_CreateSurface (pScreenPriv->pdd2, &ddsd, &pScreenPriv->pddsShadow, NULL); if (FAILED (ddrval)) { ErrorF ("winAllocateFBShadowDD - Could not create shadow "\ "surface: %08x\n", (unsigned int) ddrval); return FALSE; } #if CYGDEBUG winDebug ("winAllocateFBShadowDD - Created shadow\n"); #endif /* Allocate a DD surface description for our screen privates */ pddsdShadow = pScreenPriv->pddsdShadow = malloc (sizeof (DDSURFACEDESC)); if (pddsdShadow == NULL) { ErrorF ("winAllocateFBShadowDD - Could not allocate surface "\ "description memory\n"); return FALSE; } ZeroMemory (pddsdShadow, sizeof (*pddsdShadow)); pddsdShadow->dwSize = sizeof (*pddsdShadow); #if CYGDEBUG winDebug ("winAllocateFBShadowDD - Locking shadow\n"); #endif /* Lock the shadow surface */ ddrval = IDirectDrawSurface2_Lock (pScreenPriv->pddsShadow, NULL, pddsdShadow, DDLOCK_WAIT, NULL); if (FAILED (ddrval) || pddsdShadow->lpSurface == NULL) { ErrorF ("winAllocateFBShadowDD - Could not lock shadow "\ "surface: %08x\n", (unsigned int) ddrval); return FALSE; } #if CYGDEBUG winDebug ("winAllocateFBShadowDD - Locked shadow\n"); #endif /* We don't know how to deal with anything other than RGB */ if (!(pddsdShadow->ddpfPixelFormat.dwFlags & DDPF_RGB)) { ErrorF ("winAllocateFBShadowDD - Color format other than RGB\n"); return FALSE; } /* Grab the pitch from the surface desc */ pScreenInfo->dwStride = (pddsdShadow->u1.lPitch * 8) / pScreenInfo->dwBPP; /* Save the pointer to our surface memory */ pScreenInfo->pfb = pddsdShadow->lpSurface; /* Grab the color depth and masks from the surface description */ pScreenPriv->dwRedMask = pddsdShadow->ddpfPixelFormat.u2.dwRBitMask; pScreenPriv->dwGreenMask = pddsdShadow->ddpfPixelFormat.u3.dwGBitMask; pScreenPriv->dwBlueMask = pddsdShadow->ddpfPixelFormat.u4.dwBBitMask; #if CYGDEBUG winDebug ("winAllocateFBShadowDD - Returning\n"); #endif return TRUE; }
static int DirectXOpenDDraw(vout_display_t *vd) { vout_display_sys_t *sys = vd->sys; HRESULT hr; /* */ HRESULT (WINAPI *OurDirectDrawCreate)(GUID *,LPDIRECTDRAW *,IUnknown *); OurDirectDrawCreate = (void *)GetProcAddress(sys->hddraw_dll, _T("DirectDrawCreate")); if (!OurDirectDrawCreate) { msg_Err(vd, "DirectXInitDDraw failed GetProcAddress"); return VLC_EGENERIC; } /* */ HRESULT (WINAPI *OurDirectDrawEnumerateEx)(LPDDENUMCALLBACKEXA, LPVOID, DWORD); OurDirectDrawEnumerateEx = (void *)GetProcAddress(sys->hddraw_dll, _T("DirectDrawEnumerateExA")); if (OurDirectDrawEnumerateEx) { char *device = var_GetString(vd, "directx-device"); if (device) { msg_Dbg(vd, "directx-device: %s", device); free(device); } sys->hmonitor = MonitorFromWindow(sys->hwnd, MONITOR_DEFAULTTONEAREST); /* Enumerate displays */ OurDirectDrawEnumerateEx(DirectXOpenDDrawCallback, vd, DDENUM_ATTACHEDSECONDARYDEVICES); } /* Initialize DirectDraw now */ LPDIRECTDRAW ddobject; hr = OurDirectDrawCreate(sys->display_driver, &ddobject, NULL); if (hr != DD_OK) { msg_Err(vd, "DirectXInitDDraw cannot initialize DDraw"); return VLC_EGENERIC; } /* Get the IDirectDraw2 interface */ hr = IDirectDraw_QueryInterface(ddobject, &IID_IDirectDraw2, &sys->ddobject); /* Release the unused interface */ IDirectDraw_Release(ddobject); if (hr != DD_OK) { msg_Err(vd, "cannot get IDirectDraw2 interface"); sys->ddobject = NULL; return VLC_EGENERIC; } /* Set DirectDraw Cooperative level, ie what control we want over Windows * display */ hr = IDirectDraw2_SetCooperativeLevel(sys->ddobject, NULL, DDSCL_NORMAL); if (hr != DD_OK) { msg_Err(vd, "cannot set direct draw cooperative level"); return VLC_EGENERIC; } /* Get the size of the current display device */ if (sys->hmonitor) { MONITORINFO monitor_info; monitor_info.cbSize = sizeof(MONITORINFO); GetMonitorInfoA(vd->sys->hmonitor, &monitor_info); sys->rect_display = monitor_info.rcMonitor; } else { sys->rect_display.left = 0; sys->rect_display.top = 0; sys->rect_display.right = GetSystemMetrics(SM_CXSCREEN); sys->rect_display.bottom = GetSystemMetrics(SM_CYSCREEN); } msg_Dbg(vd, "screen dimensions (%lix%li,%lix%li)", sys->rect_display.left, sys->rect_display.top, sys->rect_display.right, sys->rect_display.bottom); /* Probe the capabilities of the hardware */ DirectXGetDDrawCaps(vd); return VLC_SUCCESS; }
// // - returns true if DirectDraw was initialized properly // int InitDirectDrawe (HWND appWin, int width, int height, int bpp, int fullScr) { DDSURFACEDESC ddsd; // DirectDraw surface description for allocating DDSCAPS ddscaps; HRESULT ddrval; DWORD dwStyle; RECT rect; // enumerate directdraw devices //if (FAILED(DirectDrawEnumerate (myEnumDDDevicesCallback, NULL))) // I_Error("Error with DirectDrawEnumerate"); if (!DDr2) CreateDirectDrawInstance(); // remember what screen mode we are in bAppFullScreen = fullScr; ScreenHeight = height; ScreenWidth = width; if (bAppFullScreen) { // Change window attributes dwStyle = WS_POPUP | WS_VISIBLE; SetWindowLong (appWin, GWL_STYLE, dwStyle); SetWindowPos(appWin, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER); // Get exclusive mode ddrval = IDirectDraw2_SetCooperativeLevel(DDr2, appWin, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN | DDSCL_ALLOWREBOOT); if (ddrval != DD_OK) I_Error("SetCooperativeLevel FAILED: %s\n", DXErrorToString(ddrval)); // Switch from windows desktop to fullscreen #ifdef NT4COMPAT ddrval = IDirectDraw2_SetDisplayMode(DDr2, width, height, bpp, 0, 0); #else ddrval = IDirectDraw2_SetDisplayMode(DDr2, width, height, bpp, 0, DDSDM_STANDARDVGAMODE); #endif if (ddrval != DD_OK) I_Error("SetDisplayMode FAILED: %s\n", DXErrorToString(ddrval)); // This is not really needed, except in certain cases. One case // is while using MFC. When the desktop is initally at 16bpp, a mode // switch to 8bpp somehow causes the MFC window to not fully initialize // and a CreateSurface will fail with DDERR_NOEXCLUSIVEMODE. This will // ensure that the window is initialized properly after a mode switch. ShowWindow(appWin, SW_SHOW); // Create the primary surface with 1 back buffer. Always zero the // DDSURFACEDESC structure and set the dwSize member! ZeroMemory(&ddsd, sizeof (ddsd)); ddsd.dwSize = sizeof (ddsd); ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT; ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_FLIP | DDSCAPS_COMPLEX; // for fullscreen we use page flipping, for windowed mode, we blit the hidden surface to // the visible surface, in both cases we have a visible (or 'real') surface, and a hidden // (or 'virtual', or 'backbuffer') surface. ddsd.dwBackBufferCount = 2; ddrval = IDirectDraw2_CreateSurface(DDr2,&ddsd, &ScreenReal, NULL); if (ddrval != DD_OK) I_Error("CreateSurface Primary Screen FAILED"); // Get a pointer to the back buffer ddscaps.dwCaps = DDSCAPS_BACKBUFFER; ddrval = IDirectDrawSurface_GetAttachedSurface(ScreenReal,&ddscaps, &ScreenVirtual); if (ddrval != DD_OK) I_Error("GetAttachedSurface FAILED"); } else { rect.top = 0; rect.left = 0; rect.bottom = height; rect.right = width; // Change window attributes dwStyle = GetWindowStyle(appWin); dwStyle &= ~WS_POPUP; dwStyle |= WS_OVERLAPPED | WS_SYSMENU | WS_CAPTION; SetWindowLong(appWin, GWL_STYLE, dwStyle); // Resize the window so that the client area is the requested width/height AdjustWindowRectEx(&rect, GetWindowStyle(appWin), GetMenu(appWin) != NULL, GetWindowExStyle(appWin)); // Just in case the window was moved off the visible area of the // screen. SetWindowPos(appWin, NULL, 0, 0, rect.right-rect.left, rect.bottom-rect.top, SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE); SetWindowPos(appWin, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE); // Exclusive mode is normal since it's in windowed mode and needs // to cooperate with GDI ddrval = IDirectDraw2_SetCooperativeLevel(DDr2,appWin, DDSCL_NORMAL); if (ddrval != DD_OK) I_Error("SetCooperativeLevel FAILED"); // Always zero the DDSURFACEDESC structure and set the dwSize member! ZeroMemory(&ddsd, sizeof (ddsd)); ddsd.dwSize = sizeof (ddsd); ddsd.dwFlags = DDSD_CAPS; ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; // Create the primary surface ddrval = IDirectDraw2_CreateSurface(DDr2,&ddsd, &ScreenReal, NULL); if (ddrval != DD_OK) I_Error("CreateSurface Primary Screen FAILED"); // Create a back buffer for offscreen rendering, this will be used to // blt to the primary ScreenVirtual = CreateNewSurface(width, height, DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY); if (ScreenVirtual == NULL) I_Error("CreateSurface Secondary Screen FAILED"); /// \todo get the desktop bit depth, and build a lookup table /// for quick conversions of 8bit color indexes 0-255 to desktop colors /// eg: 256 entries of equivalent of palette colors 0-255 in 15,16,24,32 bit format /// when blit virtual to real, convert pixels through lookup table.. // Use a clipper object for clipping when in windowed mode // (make sure our drawing doesn't affect other windows) ddrval = IDirectDraw2_CreateClipper (DDr2, 0, &windclip, 0); if (ddrval != DD_OK) I_Error("CreateClipper FAILED"); // Associate the clipper with the window. ddrval = IDirectDrawClipper_SetHWnd (windclip,0, appWin); if (ddrval != DD_OK) I_Error("Clipper -> SetHWnd FAILED"); // Attach the clipper to the surface. ddrval = IDirectDrawSurface_SetClipper (ScreenReal,windclip); if (ddrval != DD_OK) I_Error("PrimaryScreen -> SetClipperClipper FAILED"); } return TRUE; }
Bool winAllocateFBPrimaryDD (ScreenPtr pScreen) { winScreenPriv(pScreen); winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; HRESULT ddrval = DD_OK; DDSURFACEDESC ddsd; DDSURFACEDESC *pddsdPrimary = NULL; DDSURFACEDESC *pddsdOffscreen = NULL; RECT rcClient; ErrorF ("winAllocateFBPrimaryDD\n"); /* Get client area location in screen coords */ GetClientRect (pScreenPriv->hwndScreen, &rcClient); MapWindowPoints (pScreenPriv->hwndScreen, HWND_DESKTOP, (LPPOINT)&rcClient, 2); /* Create a DirectDraw object, store the address at lpdd */ ddrval = (*g_fpDirectDrawCreate) (NULL, &pScreenPriv->pdd, NULL); if (ddrval != DD_OK) FatalError ("winAllocateFBPrimaryDD - Could not start DirectDraw\n"); /* Get a DirectDraw2 interface pointer */ ddrval = IDirectDraw_QueryInterface (pScreenPriv->pdd, &IID_IDirectDraw2, (LPVOID*) &pScreenPriv->pdd2); if (FAILED (ddrval)) { ErrorF ("winAllocateFBShadowDD - Failed DD2 query: %08x\n", ddrval); return FALSE; } ErrorF ("winAllocateFBPrimaryDD - Created and initialized DD\n"); /* Are we windowed or fullscreen? */ if (pScreenInfo->fFullScreen) { /* Full screen mode */ ddrval = IDirectDraw2_SetCooperativeLevel (pScreenPriv->pdd2, pScreenPriv->hwndScreen, DDSCL_FULLSCREEN | DDSCL_EXCLUSIVE); if (FAILED (ddrval)) FatalError ("winAllocateFBPrimaryDD - Could not set " "cooperative level\n"); /* Change the video mode to the mode requested */ ddrval = IDirectDraw2_SetDisplayMode (pScreenPriv->pdd2, pScreenInfo->dwWidth, pScreenInfo->dwHeight, pScreenInfo->dwBPP, pScreenInfo->dwRefreshRate, 0); if (FAILED (ddrval)) FatalError ("winAllocateFBPrimaryDD - Could not set " "full screen display mode\n"); } else { /* Windowed mode */ ddrval = IDirectDraw2_SetCooperativeLevel (pScreenPriv->pdd2, pScreenPriv->hwndScreen, DDSCL_NORMAL); if (FAILED (ddrval)) FatalError ("winAllocateFBPrimaryDD - Could not set " "cooperative level\n"); } /* Describe the primary surface */ ZeroMemory (&ddsd, sizeof (ddsd)); ddsd.dwSize = sizeof (ddsd); ddsd.dwFlags = DDSD_CAPS; ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; /* Create the primary surface */ ddrval = IDirectDraw2_CreateSurface (pScreenPriv->pdd2, &ddsd, &pScreenPriv->pddsPrimary, NULL); if (FAILED (ddrval)) FatalError ("winAllocateFBPrimaryDD - Could not create primary " "surface %08x\n", ddrval); ErrorF ("winAllocateFBPrimaryDD - Created primary\n"); /* Allocate a DD surface description for our screen privates */ pddsdPrimary = pScreenPriv->pddsdPrimary = malloc (sizeof (DDSURFACEDESC)); if (pddsdPrimary == NULL) FatalError ("winAllocateFBPrimaryDD - Could not allocate surface " "description memory\n"); ZeroMemory (pddsdPrimary, sizeof (*pddsdPrimary)); pddsdPrimary->dwSize = sizeof (*pddsdPrimary); /* Describe the offscreen surface to be created */ /* * NOTE: Do not use a DDSCAPS_VIDEOMEMORY surface, * as drawing, locking, and unlocking take forever * with video memory surfaces. In addition, * video memory is a somewhat scarce resource, * so you shouldn't be allocating video memory when * you have the option of using system memory instead. */ ZeroMemory (&ddsd, sizeof (ddsd)); ddsd.dwSize = sizeof (ddsd); ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH; ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY; ddsd.dwHeight = pScreenInfo->dwHeight; ddsd.dwWidth = pScreenInfo->dwWidth; /* Create the shadow surface */ ddrval = IDirectDraw2_CreateSurface (pScreenPriv->pdd2, &ddsd, &pScreenPriv->pddsOffscreen, NULL); if (ddrval != DD_OK) FatalError ("winAllocateFBPrimaryDD - Could not create shadow " "surface\n"); ErrorF ("winAllocateFBPrimaryDD - Created offscreen\n"); /* Allocate a DD surface description for our screen privates */ pddsdOffscreen = pScreenPriv->pddsdOffscreen = malloc (sizeof (DDSURFACEDESC)); if (pddsdOffscreen == NULL) FatalError ("winAllocateFBPrimaryDD - Could not allocate surface " "description memory\n"); ZeroMemory (pddsdOffscreen, sizeof (*pddsdOffscreen)); pddsdOffscreen->dwSize = sizeof (*pddsdOffscreen); ErrorF ("winAllocateFBPrimaryDD - Locking primary\n"); /* Lock the primary surface */ ddrval = IDirectDrawSurface2_Lock (pScreenPriv->pddsPrimary, pScreenInfo->fFullScreen ? NULL:&rcClient, pddsdPrimary, DDLOCK_WAIT, NULL); if (ddrval != DD_OK || pddsdPrimary->lpSurface == NULL) FatalError ("winAllocateFBPrimaryDD - Could not lock " "primary surface\n"); ErrorF ("winAllocateFBPrimaryDD - Locked primary\n"); /* We don't know how to deal with anything other than RGB */ if (!(pddsdPrimary->ddpfPixelFormat.dwFlags & DDPF_RGB)) FatalError ("winAllocateFBPrimaryDD - Color format other than RGB\n"); /* Grab the pitch from the surface desc */ pScreenInfo->dwStride = (pddsdPrimary->u1.lPitch * 8) / pScreenInfo->dwBPP; /* Save the pointer to our surface memory */ pScreenInfo->pfb = pddsdPrimary->lpSurface; /* Grab the color depth and masks from the surface description */ pScreenPriv->dwRedMask = pddsdPrimary->ddpfPixelFormat.u2.dwRBitMask; pScreenPriv->dwGreenMask = pddsdPrimary->ddpfPixelFormat.u3.dwGBitMask; pScreenPriv->dwBlueMask = pddsdPrimary->ddpfPixelFormat.u4.dwBBitMask; ErrorF ("winAllocateFBPrimaryDD - Returning\n"); return TRUE; }
int directdraw_init(HWND hwndp) { int width = 320, height = 200; RECT rect; DDPIXELFORMAT format; DDSURFACEDESC descriptor; DIRECTDRAWCREATE DirectDrawCreate; if(lpDDS) return 0; if(!hwndp) return 0; if(video_window) return 0; /* you gotta uninitialize it first */ library = (HMODULE) LoadLibrary(uni("ddraw.dll")); if(!library) return 0; DirectDrawCreate = (DIRECTDRAWCREATE) GetProcAddress(library, "DirectDrawCreate"); if(!DirectDrawCreate) return 0; if(FAILED(DirectDrawCreate(0,&lpDD,0))) return 0; wc.style = CS_VREDRAW | CS_HREDRAW | CS_DBLCLKS; wc.lpfnWndProc = WndProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = 0; wc.hIcon = 0; wc.hCursor = LoadCursor(0, IDC_ARROW); wc.hbrBackground = 0; wc.lpszMenuName = 0; wc.lpszClassName = window_class_name; RegisterClass(&wc); video_window = CreateWindow(window_class_name, uni("Video"), WS_CHILD, 0, 0, width, height, hwndp, 0, 0, 0); ShowWindow(video_window, SW_NORMAL); if(FAILED(IDirectDraw2_SetCooperativeLevel(lpDD, video_window, DDSCL_NORMAL))) return 0; descriptor.dwSize = sizeof(descriptor); descriptor.dwFlags = DDSD_CAPS; descriptor.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_VIDEOMEMORY; if(FAILED(IDirectDraw2_CreateSurface(lpDD, &descriptor, &lpDDS, 0))) return 0; descriptor.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH; descriptor.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN; descriptor.dwWidth = d_width ; descriptor.dwHeight = d_height; if(FAILED(IDirectDraw2_CreateSurface(lpDD, &descriptor, &lpDDS_secondary, 0))) return 0; if(FAILED(IDirectDraw2_CreateClipper(lpDD, 0, &lpDDC, 0))) return 0; if(FAILED(IDirectDrawClipper_SetHWnd(lpDDC, 0, video_window))) return 0; if(FAILED(IDirectDrawSurface2_SetClipper(lpDDS, lpDDC))) return 0; lpDDS_back = lpDDS_secondary; format.dwSize = sizeof(format); if(FAILED(IDirectDrawSurface2_GetPixelFormat(lpDDS, &format))) return 0; if(!(format.dwFlags & DDPF_RGB)) return 0; IDirectDraw2_EnumDisplayModes(lpDD, DDEDM_STANDARDVGAMODES, 0, 0, EnumDisplayModesCallback); osd_initialize(); osd_created = 0; return 1; }
static int DDCreateSurface(directx_priv *priv, ggi_mode *mode) { HRESULT hr; LPDIRECTDRAWCLIPPER pClipper; DDSURFACEDESC pddsd, bddsd; int i; if (!priv->fullscreen) IDirectDraw2_SetCooperativeLevel(priv->lpddext, priv->hWnd, DDSCL_NORMAL); else { /* Only the thread that has excluse access (Cooperative level) * may restore the surfaces when they are lost. Therefore * let the helper thread get exclusive access so that it can * later do restores. */ directx_fullscreen dxfull; dxfull.priv = priv; dxfull.mode = mode; dxfull.event = CreateEvent(NULL, FALSE, FALSE, NULL); PostThreadMessage(priv->nThreadID, WM_DDFULLSCREEN, 0, (long)&dxfull); WaitForSingleObject(dxfull.event, INFINITE); CloseHandle(dxfull.event); } /* create the primary surface */ memset(&pddsd, 0, sizeof(pddsd)); pddsd.dwSize = sizeof(pddsd); pddsd.dwFlags = DDSD_CAPS; pddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; if (priv->fullscreen) pddsd.ddsCaps.dwCaps |= DDSCAPS_VIDEOMEMORY; hr = IDirectDraw2_CreateSurface(priv->lpddext, &pddsd, &priv->lppdds, NULL); if (hr != 0) { fprintf(stderr, "Init Primary Surface Failed RC = %lx. Exiting\n", hr); exit(-1); } IDirectDraw2_CreateClipper(priv->lpddext, 0, &pClipper, NULL); IDirectDrawClipper_SetHWnd(pClipper, 0, priv->hWnd); IDirectDrawSurface_SetClipper(priv->lppdds, pClipper); IDirectDrawClipper_Release(pClipper); pddsd.dwSize = sizeof(pddsd); IDirectDrawSurface_GetSurfaceDesc(priv->lppdds, &pddsd); DPRINT_MISC("DDraw pixel format:\n"); DPRINT_MISC(" Size %u\n", pddsd.ddpfPixelFormat.dwSize); DPRINT_MISC(" Flags %08x\n", pddsd.ddpfPixelFormat.dwFlags); DPRINT_MISC(" FourCC %08x\n", pddsd.ddpfPixelFormat.dwFourCC); DPRINT_MISC(" Count %u\n", pddsd.ddpfPixelFormat.dwRGBBitCount); DPRINT_MISC(" R-Mask(etc) %08x\n", pddsd.ddpfPixelFormat.dwRBitMask); DPRINT_MISC(" G-Mask(etc) %08x\n", pddsd.ddpfPixelFormat.dwGBitMask); DPRINT_MISC(" B-Mask(etc) %08x\n", pddsd.ddpfPixelFormat.dwBBitMask); DPRINT_MISC(" Z-Mask(etc) %08x\n", pddsd.ddpfPixelFormat.dwRGBZBitMask); /* create the back storages */ for (i = 0; i < mode->frames; ++i) { memset(&bddsd, 0, sizeof(bddsd)); bddsd.dwSize = sizeof(bddsd); bddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT; bddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY; bddsd.dwWidth = mode->virt.x; bddsd.dwHeight = mode->virt.y; /* set up the pixel format */ ZeroMemory(&bddsd.ddpfPixelFormat, sizeof(DDPIXELFORMAT)); bddsd.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT); bddsd.ddpfPixelFormat.dwFlags = pddsd.ddpfPixelFormat.dwFlags; bddsd.ddpfPixelFormat.dwFourCC = pddsd.ddpfPixelFormat.dwFourCC; bddsd.ddpfPixelFormat.dwRGBBitCount = pddsd.ddpfPixelFormat.dwRGBBitCount; bddsd.ddpfPixelFormat.dwRBitMask = pddsd.ddpfPixelFormat.dwRBitMask; bddsd.ddpfPixelFormat.dwGBitMask = pddsd.ddpfPixelFormat.dwGBitMask; bddsd.ddpfPixelFormat.dwBBitMask = pddsd.ddpfPixelFormat.dwBBitMask; bddsd.ddpfPixelFormat.dwRGBAlphaBitMask = pddsd.ddpfPixelFormat.dwRGBAlphaBitMask; hr = IDirectDraw2_CreateSurface(priv->lpddext, &bddsd, &priv->lpbdds[i], NULL); if (hr) { fprintf(stderr, "Init Backup Failed RC = %lx. Exiting\n", hr); exit(-1); } IDirectDrawSurface2_Lock(priv->lpbdds[i], NULL, &bddsd, DDLOCK_SURFACEMEMORYPTR, NULL); priv->lpSurfaceAdd[i] = (char *) bddsd.lpSurface; IDirectDrawSurface2_Unlock(priv->lpbdds[i], bddsd.lpSurface); } /* set private mode parameters */ priv->maxX = mode->virt.x; priv->maxY = mode->virt.y; priv->ColorDepth = pddsd.ddpfPixelFormat.dwRGBBitCount; priv->pitch = bddsd.lPitch; if (pddsd.ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED8) { static PALETTEENTRY pal[256]; /* todo fill in pal */ hr = IDirectDraw_CreatePalette(priv->lpddext, DDPCAPS_8BIT|DDPCAPS_ALLOW256, pal, &priv->lpddp, NULL); if (hr) { fprintf(stderr, "Init Palette failed RC = %lx. Exiting\n", hr); exit(-1); } hr = IDirectDrawSurface_SetPalette(priv->lppdds, priv->lpddp); if (hr) { fprintf(stderr, "Install Palette failed RC = %lx. Exiting\n", hr); exit(-1); } } return 1; }
static unsigned __stdcall DDEventLoop(void *lpParm) { MSG msg; struct ggi_visual *vis = (struct ggi_visual *) lpParm; directx_priv *priv = GGIDIRECTX_PRIV(vis); priv->nThreadID = GetCurrentThreadId(); /* create the window */ if (!DDCreateWindow(vis)) { SetEvent(priv->hInit); return 0; } SetEvent(priv->hInit); while (GetMessage(&msg, NULL, 0, 0)) { if (msg.hwnd == NULL && msg.message == WM_DDEND) { /* Use PostThreadMessage to get here */ DPRINT("Ending session, " "destroying window.\n"); DestroyWindow(priv->hWnd); break; } if (msg.hwnd == NULL && msg.message == WM_DDFULLSCREEN) { directx_fullscreen *dxfull = (directx_fullscreen *)msg.lParam; if (!dxfull) { fprintf(stderr, "Aieee! " "No lParam for WM_DDFULLSCREEN\n"); exit(1); } DPRINT_MODE("Set coop level\n"); dxfull->hr = IDirectDraw2_SetCooperativeLevel( dxfull->priv->lpddext, dxfull->priv->hWnd, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN); if (FAILED(dxfull->hr)) DPRINT_MODE("SetCooperativeLevel failed %x\n", dxfull->hr); DPRINT_MODE("Set fullscreen mode " "(%i,%i) size %d\n", dxfull->mode->visible.x, dxfull->mode->visible.y, GT_SIZE(dxfull->mode->graphtype)); dxfull->hr = IDirectDraw2_SetDisplayMode( dxfull->priv->lpddext, dxfull->mode->visible.x, dxfull->mode->visible.y, GT_SIZE(dxfull->mode->graphtype), 0, 0); if (FAILED(dxfull->hr)) DPRINT_MODE("SetDisplayMode failed %x\n", dxfull->hr); SetEvent(dxfull->event); continue; } if (msg.hwnd == NULL && msg.message == WM_DDHOTKEY) { if (msg.wParam) { DPRINT("Grab hotkeys\n"); RegisterHotKey(priv->hWnd, 0x0000, MOD_ALT, VK_TAB); RegisterHotKey(priv->hWnd, 0x0001, MOD_ALT | MOD_SHIFT, VK_TAB); RegisterHotKey(priv->hWnd, 0x0002, MOD_ALT, VK_F4); } else { DPRINT("Ungrab hotkeys\n"); UnregisterHotKey(priv->hWnd, 0x0000); UnregisterHotKey(priv->hWnd, 0x0001); UnregisterHotKey(priv->hWnd, 0x0002); } continue; } TranslateMessage(&msg); DispatchMessage(&msg); } DPRINT("Helper thread terminating\n"); #ifndef __CYGWIN__ _endthreadex(msg.wParam); #endif return msg.wParam; }
static int ResizeDD(int fullscreen) { HRESULT ddrval; DDSURFACEDESC ddsd; /*DDCAPS2 ddscaps; */ LPDIRECTDRAWCLIPPER pClipper; int dxwidth; int dxheight; int dxbpp; // free DirectX objects if (lpSurfaces[0]) IDirectDrawSurface_Release(lpSurfaces[0]); lpSurfaces[0] = NULL; if (dxPalette) IDirectDrawPalette_Release(dxPalette); dxPalette = NULL; /* Set cooperative level */ ddrval = IDirectDraw2_SetCooperativeLevel(lpDD2, hWnd, fullscreen ? (DDSCL_FULLSCREEN | DDSCL_EXCLUSIVE | DDSCL_ALLOWREBOOT) : DDSCL_NORMAL); if (ddrval != DD_OK) { DeInitDD(); x_error("Failed to set cooperative level"); return 0; } if (fullscreen) { if (sscanf(dxsize, "%ix%ix%i", &dxwidth, &dxheight, &dxbpp) != 3) { dxwidth = DXWIDTH; dxheight = DXHEIGHT; dxbpp = DXBPP; } displayX = dxwidth; displayY = dxheight; bitDepth = dxbpp; if (bitDepth < 10) bitDepth = 8; if (bitDepth >= 10 && bitDepth < 20) bitDepth = 16; if (bitDepth >= 20 && bitDepth < 28) bitDepth = 24; if (bitDepth >= 32 && bitDepth < 32) bitDepth = 32; /* set resolution and bit depth */ ddrval = IDirectDraw2_SetDisplayMode(lpDD2, displayX, displayY, bitDepth, 0, 0); if (ddrval != DD_OK) { /* The display mode cannot be changed. The mode is either not supported or another application has exclusive mode. Try 320x200x256 and 640x480x256 modes before giving up */ displayX = 320; displayY = 200; bitDepth = 8; ddrval = IDirectDraw2_SetDisplayMode(lpDD2, displayX, displayY, bitDepth, 0, 0); if (ddrval != DD_OK) { displayY = 240; if (ddrval != DD_OK) { displayX = 640; displayY = 480; ddrval = IDirectDraw2_SetDisplayMode(lpDD2, displayX, displayY, bitDepth, 0, 0); if (ddrval != DD_OK) { /* Bad luck... give up. */ DeInitDD(); return 0; } } } } SetRect(&rcViewport, 0, 0, displayX, displayY); rcScreen = rcViewport; } else { /* Get the dimensions of the viewport and screen bounds */ GetClientRect(hWnd, &rcViewport); GetClientRect(hWnd, &rcScreen); ClientToScreen(hWnd, (POINT *) & rcScreen.left); ClientToScreen(hWnd, (POINT *) & rcScreen.right); /*bitDepth = GetDeviceCaps (hDC, BITSPIXEL); */ /* Create clipper object for window */ ddrval = IDirectDraw_CreateClipper(lpDD, 0, &pClipper, NULL); if (ddrval != DD_OK) { DeInitDD(); x_error("Failed to create clipper object"); return 0; } /* Asociate it */ IDirectDrawClipper_SetHWnd(pClipper, 0, hWnd); } /* Create the primary surface with one back buffer */ CalculateBITMAPINFO(); // calculate BITMAPINFO structure memset(&ddsd, 0, sizeof(ddsd)); ddsd.dwSize = sizeof(ddsd); ddsd.dwFlags = DDSD_CAPS; ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; ddrval = IDirectDraw_CreateSurface(lpDD, &ddsd, &lpSurfaces[0], NULL); if (ddrval != DD_OK) { DeInitDD(); x_error("Failed to create flipping surface"); return 0; } if (!fullscreen) { IDirectDrawSurface_SetClipper(lpSurfaces[0], pClipper); IDirectDrawClipper_Release(pClipper); if (IDirectDrawSurface_GetSurfaceDesc(lpSurfaces[0], &ddsd) != DD_OK) { DeInitDD(); x_error("Failed to get pixel format"); return 0; } bitDepth = ddsd.ddpfPixelFormat.u1.dwRGBBitCount; } if (bitDepth == 8) { /* create palette */ ddrval = IDirectDraw_CreatePalette(lpDD, DDPCAPS_8BIT, (LPPALETTEENTRY) bmp->bmiColors, &dxPalette, NULL); if (ddrval != DD_OK) { DeInitDD(); x_error("Failed to create palette"); return 0; } /* set palette */ IDirectDrawSurface_SetPalette(lpSurfaces[0], dxPalette); } if (fullscreen) SetCursor(NULL); needredraw = 1; return 1; }