/*
*Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved.
*
*Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
*"Software"), to deal in the Software without restriction, including
*without limitation the rights to use, copy, modify, merge, publish,
*distribute, sublicense, and/or sell copies of the Software, and to
*permit persons to whom the Software is furnished to do so, subject to
*the following conditions:
*
*The above copyright notice and this permission notice shall be
*included in all copies or substantial portions of the Software.
*
*THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
*EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
*MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
*NONINFRINGEMENT. IN NO EVENT SHALL THE XFREE86 PROJECT BE LIABLE FOR
*ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
*CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
*WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*Except as contained in this notice, the name of the XFree86 Project
*shall not be used in advertising or otherwise to promote the sale, use
*or other dealings in this Software without prior written authorization
*from the XFree86 Project.
*
* Authors: Harold L Hunt II
*/
#ifdef HAVE_XWIN_CONFIG_H
#include <xwin-config.h>
#endif
#include "win.h"
/*
* External symbols
*/
extern HWND g_hDlgExit;
/*
* Local function prototypes
*/
static Bool
winAllocateFBNativeGDI (ScreenPtr pScreen);
static void
winShadowUpdateNativeGDI (ScreenPtr pScreen,
shadowBufPtr pBuf);
static Bool
winCloseScreenNativeGDI (int nIndex, ScreenPtr pScreen);
static Bool
winInitVisualsNativeGDI (ScreenPtr pScreen);
static Bool
winAdjustVideoModeNativeGDI (ScreenPtr pScreen);
#if 0
static Bool
winBltExposedRegionsNativeGDI (ScreenPtr pScreen);
#endif
static Bool
winActivateAppNativeGDI (ScreenPtr pScreen);
static Bool
winRedrawScreenNativeGDI (ScreenPtr pScreen);
static Bool
winRealizeInstalledPaletteNativeGDI (ScreenPtr pScreen);
static Bool
winInstallColormapNativeGDI (ColormapPtr pColormap);
static Bool
winStoreColorsNativeGDI (ColormapPtr pmap,
int ndef,
xColorItem *pdefs);
static Bool
winCreateColormapNativeGDI (ColormapPtr pColormap);
static Bool
winDestroyColormapNativeGDI (ColormapPtr pColormap);
static Bool
winAllocateFBNativeGDI (ScreenPtr pScreen)
{
FatalError ("winAllocateFBNativeGDI\n");
return TRUE;
}
/*
* We wrap whatever CloseScreen procedure was specified by fb;
* a pointer to said procedure is stored in our privates.
*/
static Bool
winCloseScreenNativeGDI (int nIndex, ScreenPtr pScreen)
{
winScreenPriv(pScreen);
winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
ErrorF ("winCloseScreenNativeGDI - Freeing screen resources\n");
/* Flag that the screen is closed */
pScreenPriv->fClosed = TRUE;
pScreenPriv->fActive = FALSE;
/*
* NOTE: mi doesn't use a CloseScreen procedure, so we do not
* need to call a wrapped procedure here.
*/
/* Delete the window property */
RemoveProp (pScreenPriv->hwndScreen, WIN_SCR_PROP);
ErrorF ("winCloseScreenNativeGDI - Destroying window\n");
/* Delete tray icon, if we have one */
if (!pScreenInfo->fNoTrayIcon)
winDeleteNotifyIcon (pScreenPriv);
/* Free the exit confirmation dialog box, if it exists */
if (g_hDlgExit != NULL)
{
DestroyWindow (g_hDlgExit);
g_hDlgExit = NULL;
}
/* Kill our window */
if (pScreenPriv->hwndScreen)
{
DestroyWindow (pScreenPriv->hwndScreen);
pScreenPriv->hwndScreen = NULL;
}
/* Invalidate our screeninfo's pointer to the screen */
pScreenInfo->pScreen = NULL;
/* Free the screen privates for this screen */
free (pScreenPriv);
ErrorF ("winCloseScreenNativeGDI - Returning\n");
return TRUE;
}
static void
winShadowUpdateNativeGDI (ScreenPtr pScreen,
shadowBufPtr pBuf)
{
FatalError ("winShadowUpdateNativeGDI\n");
return;
}
static Bool
winInitVisualsNativeGDI (ScreenPtr pScreen)
{
winScreenPriv(pScreen);
winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
/* Set the bitsPerRGB and bit masks */
switch (pScreenInfo->dwDepth)
{
case 24:
pScreenPriv->dwBitsPerRGB = 8;
pScreenPriv->dwRedMask = 0x00FF0000;
pScreenPriv->dwGreenMask = 0x0000FF00;
pScreenPriv->dwBlueMask = 0x000000FF;
break;
case 16:
pScreenPriv->dwBitsPerRGB = 6;
pScreenPriv->dwRedMask = 0xF800;
pScreenPriv->dwGreenMask = 0x07E0;
pScreenPriv->dwBlueMask = 0x001F;
break;
case 15:
pScreenPriv->dwBitsPerRGB = 5;
pScreenPriv->dwRedMask = 0x7C00;
pScreenPriv->dwGreenMask = 0x03E0;
pScreenPriv->dwBlueMask = 0x001F;
break;
case 8:
pScreenPriv->dwBitsPerRGB = 8;
pScreenPriv->dwRedMask = 0;
pScreenPriv->dwGreenMask = 0;
pScreenPriv->dwBlueMask = 0;
break;
default:
ErrorF ("winInitVisualsNativeGDI - Unknown screen depth\n");
return FALSE;
break;
}
/* Tell the user how many bits per RGB we are using */
ErrorF ("winInitVisualsNativeGDI - Using dwBitsPerRGB: %d\n",
(int) pScreenPriv->dwBitsPerRGB);
/* Create a single visual according to the Windows screen depth */
switch (pScreenInfo->dwDepth)
{
case 24:
case 16:
case 15:
if (!miSetVisualTypesAndMasks (pScreenInfo->dwDepth,
TrueColorMask,
pScreenPriv->dwBitsPerRGB,
TrueColor,
pScreenPriv->dwRedMask,
pScreenPriv->dwGreenMask,
pScreenPriv->dwBlueMask))
{
ErrorF ("winInitVisuals - miSetVisualTypesAndMasks failed\n");
return FALSE;
}
break;
case 8:
ErrorF ("winInitVisuals - Calling miSetVisualTypesAndMasks\n");
if (!miSetVisualTypesAndMasks (pScreenInfo->dwDepth,
StaticColorMask,
pScreenPriv->dwBitsPerRGB,
StaticColor,
pScreenPriv->dwRedMask,
pScreenPriv->dwGreenMask,
pScreenPriv->dwBlueMask))
{
ErrorF ("winInitVisuals - miSetVisualTypesAndMasks failed\n");
return FALSE;
}
break;
default:
ErrorF ("winInitVisualsNativeGDI - Unknown screen depth\n");
return FALSE;
}
#if 1
ErrorF ("winInitVisualsNativeGDI - Returning\n");
#endif
return TRUE;
}
/* Adjust the video mode */
static Bool
winAdjustVideoModeNativeGDI (ScreenPtr pScreen)
{
winScreenPriv(pScreen);
winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
HDC hdc = NULL;
DWORD dwBPP;
hdc = GetDC (NULL);
/* We're in serious trouble if we can't get a DC */
if (hdc == NULL)
{
ErrorF ("winAdjustVideoModeNativeGDI - GetDC () failed\n");
return FALSE;
}
/* Query GDI for current display depth */
dwBPP = GetDeviceCaps (hdc, BITSPIXEL);
pScreenInfo->dwDepth = GetDeviceCaps (hdc, PLANES);
switch (pScreenInfo->dwDepth) {
case 24:
case 16:
case 15:
case 8:
break;
default:
if (dwBPP == 32)
pScreenInfo->dwDepth = 24;
else
pScreenInfo->dwDepth = dwBPP;
break;
}
/* GDI cannot change the screen depth */
if (pScreenInfo->dwBPP == WIN_DEFAULT_BPP)
{
/* No -depth parameter passed, let the user know the depth being used */
ErrorF ("winAdjustVideoModeNativeGDI - Using Windows display "
"depth of %d bits per pixel, %d depth\n",
(int) dwBPP, (int) pScreenInfo->dwDepth);
/* Use GDI's depth */
pScreenInfo->dwBPP = dwBPP;
}
else if (dwBPP != pScreenInfo->dwBPP)
{
/* Warn user if GDI depth is different than -depth parameter */
ErrorF ("winAdjustVideoModeNativeGDI - Command line bpp: %d, "\
"using bpp: %d\n",
(int) pScreenInfo->dwBPP, (int) dwBPP);
/* We'll use GDI's depth */
pScreenInfo->dwBPP = dwBPP;
}
/* Release our DC */
ReleaseDC (NULL, hdc);
return TRUE;
}
static Bool
winActivateAppNativeGDI (ScreenPtr pScreen)
{
winScreenPriv(pScreen);
winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
/*
* Are we active?
* Are we fullscreen?
*/
if (pScreenPriv != NULL
&& pScreenPriv->fActive
&& pScreenInfo->fFullScreen)
{
/*
* Activating, attempt to bring our window
* to the top of the display
*/
ShowWindow (pScreenPriv->hwndScreen, SW_RESTORE);
}
/*
* Are we inactive?
* Are we fullscreen?
*/
if (pScreenPriv != NULL
&& !pScreenPriv->fActive
&& pScreenInfo->fFullScreen)
{
/*
* Deactivating, stuff our window onto the
* task bar.
*/
ShowWindow (pScreenPriv->hwndScreen, SW_MINIMIZE);
}
return TRUE;
}
HBITMAP
winCreateDIBNativeGDI (int iWidth, int iHeight, int iDepth,
BYTE **ppbBits, BITMAPINFO **ppbmi)
{
BITMAPINFOHEADER *pbmih = NULL;
HBITMAP hBitmap = NULL;
BITMAPINFO *pbmi = NULL;
/* Don't create an invalid bitmap */
if (iWidth == 0
|| iHeight == 0
|| iDepth == 0)
{
ErrorF ("\nwinCreateDIBNativeGDI - Invalid specs w %d h %d d %d\n\n",
iWidth, iHeight, iDepth);
return NULL;
}
/* Allocate bitmap info header */
pbmih = (BITMAPINFOHEADER*) malloc (sizeof (BITMAPINFOHEADER)
+ 256 * sizeof (RGBQUAD));
if (pbmih == NULL)
{
ErrorF ("winCreateDIBNativeGDI - malloc () failed\n");
return FALSE;
}
ZeroMemory (pbmih, sizeof(BITMAPINFOHEADER) + 256 * sizeof (RGBQUAD));
/* Describe bitmap to be created */
pbmih->biSize = sizeof (BITMAPINFOHEADER);
pbmih->biWidth = iWidth;
pbmih->biHeight = -iHeight;
pbmih->biPlanes = 1;
pbmih->biBitCount = iDepth;
pbmih->biCompression = BI_RGB;
pbmih->biSizeImage = 0;
pbmih->biXPelsPerMeter = 0;
pbmih->biYPelsPerMeter = 0;
pbmih->biClrUsed = 0;
pbmih->biClrImportant = 0;
/* Setup color table for mono DIBs */
if (iDepth == 1)
{
pbmi = (BITMAPINFO*) pbmih;
pbmi->bmiColors[1].rgbBlue = 255;
pbmi->bmiColors[1].rgbGreen = 255;
pbmi->bmiColors[1].rgbRed = 255;
}
/* Create a DIB with a bit pointer */
hBitmap = CreateDIBSection (NULL,
(BITMAPINFO *) pbmih,
DIB_RGB_COLORS,
(void **) ppbBits,
NULL,
0);
if (hBitmap == NULL)
{
ErrorF ("winCreateDIBNativeGDI - CreateDIBSection () failed\n");
return NULL;
}
/* Free the bitmap info header memory */
if (ppbmi != NULL)
{
/* Store the address of the BMIH in the ppbmih parameter */
*ppbmi = (BITMAPINFO *) pbmih;
}
else
{
free (pbmih);
pbmih = NULL;
}
return hBitmap;
}
#if 0
static Bool
winBltExposedRegionsNativeGDI (ScreenPtr pScreen)
{
return TRUE;
}
#endif
static Bool
winRedrawScreenNativeGDI (ScreenPtr pScreen)
{
FatalError ("winRedrawScreenNativeGDI\n");
return TRUE;
}
static Bool
winRealizeInstalledPaletteNativeGDI (ScreenPtr pScreen)
{
FatalError ("winRealizeInstalledPaletteNativeGDI\n");
return TRUE;
}
static Bool
winInstallColormapNativeGDI (ColormapPtr pColormap)
{
FatalError ("winInstallColormapNativeGDI\n");
return TRUE;
}
static Bool
winStoreColorsNativeGDI (ColormapPtr pmap,
int ndef,
xColorItem *pdefs)
{
FatalError ("winStoreColorsNativeGDI\n");
return TRUE;
}
static Bool
winCreateColormapNativeGDI (ColormapPtr pColormap)
{
FatalError ("winCreateColormapNativeGDI\n");
return TRUE;
}
static Bool
winDestroyColormapNativeGDI (ColormapPtr pColormap)
{
FatalError ("winDestroyColormapNativeGDI\n");
return TRUE;
}
/* Set engine specific funtions */
Bool
winSetEngineFunctionsNativeGDI (ScreenPtr pScreen)
{
winScreenPriv(pScreen);
winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
/* Set our pointers */
pScreenPriv->pwinAllocateFB = winAllocateFBNativeGDI;
pScreenPriv->pwinShadowUpdate = winShadowUpdateNativeGDI;
pScreenPriv->pwinCloseScreen = winCloseScreenNativeGDI;
pScreenPriv->pwinInitVisuals = winInitVisualsNativeGDI;
pScreenPriv->pwinAdjustVideoMode = winAdjustVideoModeNativeGDI;
if (pScreenInfo->fFullScreen)
pScreenPriv->pwinCreateBoundingWindow = winCreateBoundingWindowFullScreen;
else
pScreenPriv->pwinCreateBoundingWindow = winCreateBoundingWindowWindowed;
pScreenPriv->pwinFinishScreenInit = winFinishScreenInitNativeGDI;
/*
* WARNING: Do not set the BltExposedRegions procedure pointer to anything
* other than NULL until a working painting procedure is in place.
* Else, winWindowProc will get stuck in an infinite loop because
* Windows expects the BeginPaint and EndPaint functions to be called
* before a WM_PAINT message can be removed from the queue. We are
* using NULL here as a signal for winWindowProc that it should
* not signal that the WM_PAINT message has been processed.
*/
pScreenPriv->pwinBltExposedRegions = NULL;
pScreenPriv->pwinActivateApp = winActivateAppNativeGDI;
pScreenPriv->pwinRedrawScreen = winRedrawScreenNativeGDI;
pScreenPriv->pwinRealizeInstalledPalette =
winRealizeInstalledPaletteNativeGDI;
pScreenPriv->pwinInstallColormap = winInstallColormapNativeGDI;
pScreenPriv->pwinStoreColors = winStoreColorsNativeGDI;
pScreenPriv->pwinCreateColormap = winCreateColormapNativeGDI;
pScreenPriv->pwinDestroyColormap = winDestroyColormapNativeGDI;
pScreenPriv->pwinHotKeyAltTab = (winHotKeyAltTabProcPtr) (void (*)(void))NoopDDA;
return TRUE;
}
|