windraw2.cpp

来自「symbian 下的helix player源代码」· C++ 代码 · 共 2,002 行 · 第 1/5 页

CPP
2,002
字号

        SafeSprintf(szTemp, MAX_DISPLAY_NAME, 
                    "DisplayMode: %s %s BackBuffers: %ld Width: %ld Height: %ld%s",
                    (ddsd.ddsCaps.dwCaps & DDSCAPS_OVERLAY) ? "Overlay" : "Offscreen",
                    fourCC,
                    (ddsd.dwFlags & DDSD_BACKBUFFERCOUNT) ? ddsd.dwBackBufferCount : 0,
                    ddsd.dwWidth,
                    ddsd.dwHeight,
                    pSeparator);
        pDDInfo += szTemp;
    }
            
    BMI bmi;
    memset(&bmi, 0, sizeof(bmi));

    GetDisplayFormat(&bmi, NULL);

    // write monitor properties
    SafeSprintf(szTemp, MAX_DISPLAY_NAME,
                "Screen Width %ld Height %ld BPP: %ld%s",
                 GetSystemMetrics(SM_CXSCREEN),
                 GetSystemMetrics(SM_CYSCREEN),
                 bmi.bmiHeader.biBitCount,
                 pSeparator);
    pDDInfo += szTemp;

    pszDDInfo = new char[pDDInfo.GetLength()+1];
    if (pszDDInfo)
    {
        strncpy(pszDDInfo, pDDInfo, pDDInfo.GetLength()+1);
    }
    
    return pszDDInfo;
}

void DumpDDInfo(LPWINDRAW lpwd, LPDIRECTDRAWSURFACE lpSurface, char *pFunction)
{
    // A DirectDraw exception occured...bad bad bad
    //HX_ASSERT(0);

    // Serialize access to ddinfo.txt
    if (g_ehandlerMutexCnt)
        EnterCriticalSection(&g_ehandlerMutex);

    // Write a file in the plugins dir
    char    szPath[256]; /* Flawfinder: ignore */

    char    szFilePerm[] = "r+";
    int     nEntries = 1;
    char    szTmp[MAX_DISPLAY_NAME];     /* Flawfinder: ignore */
    char*   pszDDInfo = NULL;
    const char* pPath = NULL;
    pPath = GetDLLAccessPath()->GetPath(DLLTYPE_PLUGIN);
    SafeStrCpy(szPath, pPath, 256);
    SafeStrCat(szPath, "ddinfo.txt", 256);

    FILE *fp = fopen(szPath, "r"); /* Flawfinder: ignore */
    if (fp)
    {
        const int nMaxChars = 2048;
        int nMaxEntries = 50;

        // check log entry count
        fscanf(fp, "%s %d", szTmp, &nEntries);

        // Limit log file entries to nMaxEntries
        if (++nEntries > nMaxEntries)
        {
            char *pTime = NULL;
            SYSTEMTIME time;
            double dTime = 0;
            double dOldTime = 3000*8760;    // 3000 A.D. in hours
            int nOldestOffset = 0;
            int nLoc = 0;

            char pBuffer[nMaxChars]; /* Flawfinder: ignore */
            memset(&time, 0, sizeof(time));
            
            // read first <cr>
            fgets(pBuffer, nMaxChars, fp);

            // Find the oldest entry if the file
            while (!feof(fp))
            {
                nLoc = ftell(fp);
                fgets(pBuffer, nMaxChars, fp);
                
                // Find start of date
                pTime = strstr(pBuffer, "Systime: "); 
                if (pTime)
                {
                    // Read systime values for this log entry
                    pTime += 9;
                    sscanf(pTime, "%d %d %d %d %d %d %d %d",
                           &time.wYear, &time.wMonth, &time.wDayOfWeek,
                           &time.wDay, &time.wHour, &time.wMinute,
                           &time.wSecond, &time.wMilliseconds);

                    // Change date to hours for comparison
                    dTime = time.wYear*8760 + 
                            time.wMonth*720 + 
                            time.wDay*24 +
                            time.wHour +
                            time.wSecond/60.0 +
                            time.wMilliseconds/60000.0;
                    
                    // Compare with the current oldest entry
                    if (dTime < dOldTime)
                    {
                        dOldTime = dTime;
                        nOldestOffset = nLoc;
                    }
                }
            }

            // Remove oldest log entry: move contents of ddinfo to a temp file,
            // delete ddinfo.txt, ren. temp file to ddinfo.txt.
            pPath = GetDLLAccessPath()->GetPath(DLLTYPE_PLUGIN);
            SafeStrCpy(szTmp, pPath, 256);
            SafeStrCat(szTmp, "ddtemp.txt", 256);

            FILE *fpTemp = fopen(szTmp, "w"); /* Flawfinder: ignore */
            if (fpTemp)
            {
                fseek(fp, 0, SEEK_SET);
                while (!feof(fp))
                {
                    nLoc = ftell(fp);
                    if (fgets(pBuffer, nMaxChars, fp))
                    {
                        // Skip oldest entry
                        if (nLoc != nOldestOffset)
                            fputs(pBuffer, fpTemp);
                    }
                }
            }

            fclose(fp);

            if (fpTemp)
            {
                fclose(fpTemp);
                DeleteFile(szPath);

                rename(szTmp, szPath);
            }

            nEntries = nMaxEntries;
        }
        else
            fclose(fp);
    }
    else
    {
        szFilePerm[0] = 'w';
        szFilePerm[1] = '\0';
    }

    fp = fopen(szPath, szFilePerm); /* Flawfinder: ignore */
    if (fp)
    {
        fseek(fp, 0, SEEK_SET);
        fprintf(fp, "%s%d\t ", "Entries ", nEntries);
        fseek(fp, -1, SEEK_END);

        pszDDInfo = CollectDDInfo(lpwd, lpSurface, pFunction, "\t");
        if (pszDDInfo)
        {
            fprintf(fp, "%s", pszDDInfo);
        }
        HX_VECTOR_DELETE(pszDDInfo);

        fclose(fp);
    }

    if (g_ehandlerCount < g_ehandlerSilent)
    {
        // Need to throw error
        if (lpwd && lpwd->pErrMsg)
        {
            lpwd->pErrMsg->Report(HXLOG_INFO, HXR_WINDRAW_EXCEPTION, 0,
                                  szPath, NULL);
        }
    }

    if (lpwd && lpwd->pErrMsg)
        InterlockedIncrement(&g_ehandlerCount);

    if (g_ehandlerMutexCnt)
        LeaveCriticalSection(&g_ehandlerMutex);
}

/*
* Load system and/or bitmap palette.
*/
static int nSystemColors = 0;   /* !0 when system palette is loaded */
static	PALETTEENTRY	SystemPalette [256];
static	RGBQUAD		SystemPaletteRGB[256];
static int SystemPaletteIndices [256];

static int LoadPalette (LPWINDRAW lpwd)
{
    HDC hDC;
    int i, n = 0;
    
    /* get system palette first: */
    if ((hDC = GetDC (NULL)) != NULL) 
    {
        n = GetSystemPaletteEntries (hDC, 0, 256, SystemPalette);
        ReleaseDC (NULL,hDC);
    }
    
    /* check if system palette is loaded: */
    /* generate palette index: */
    for (i=0; i<n; i++)
    {
	SystemPaletteIndices[i]		= i;
	SystemPaletteRGB[i].rgbBlue	= SystemPalette[i].peBlue;
	SystemPaletteRGB[i].rgbGreen	= SystemPalette[i].peGreen;
	SystemPaletteRGB[i].rgbRed	= SystemPalette[i].peRed;
	SystemPaletteRGB[i].rgbReserved = 0;
    }
    
    /* update color conversion tables: */
    if (pfSetRGB8Palette)
    {
	(*pfSetRGB8Palette)(n, (unsigned long *)SystemPalette, SystemPaletteIndices);
    }
    
    /* indicate that palette is set: */
    nSystemColors = n;
    
    /* return # of colors loaded: */
    return n;
}

HRESULT CreateDirectDrawPalette (LPWINDRAW pwd, LPDIRECTDRAWSURFACE pSurface)
{
    HRESULT ddrval = E_FAIL;
    
    if (!pSurface || !pwd)
    {
        return ddrval;
    }
    
    try
    {

    /* load system palette if necessary: */
    if (nSystemColors) {

        /* create DirectDraw palette object: */
        if ((ddrval = IDirectDraw_CreatePalette (pwd->dd.lpDD2, DDPCAPS_8BIT, SystemPalette, &(pwd->dd.lpDDPal), NULL)) == DD_OK) 
        {
            /* check if we can attach palette to a primary surface: */
            if ((ddrval = IDirectDrawSurface_SetPalette (pSurface, pwd->dd.lpDDPal)) != DD_OK) 
            {
                /* release it and return error code: */
                IDirectDrawPalette_Release (pwd->dd.lpDDPal);
            }
        }
    }

    }
    catch (...)
    {
        DumpDDInfo(pwd, pSurface, "CreateDirectDrawPalette");
        ddrval = E_FAIL;
    }

    return ddrval;
}

/*
* Instructs color converters to use new destination palette:
*/
static void SetColorConverterPalette (PALETTEENTRY *pPalette, int l, int h)
{
    int i, palIdx [256];
    /* Instruct the color conversion library to use set of our
    * "standard" colors ( [l,h] range) from the logical palette:  */
    for (i=l; i<h; i++) palIdx [i] = i;
    
    if (pfSetRGB8Palette)
    {
	(*pfSetRGB8Palette)(h-l, (ULONG32*) (pPalette + l), palIdx + l);
    }
}

/*
* Checks if system palette contains our colors.
*/
static BOOL HasPaletteChanged (LPWINDRAW lpwd)
{
    PALETTEENTRY lppe [256], *lppe2;
    register int i;
    
    /* clear memory: */
    memset(lppe, 0, sizeof(lppe));
    
    /* retrive system palette: */
    if ((lpwd->fMode & WINDRAW_DIRECTDRAW) && lpwd->dd.lpDDPal != NULL &&
        /* use DirectDraw: */
        IDirectDrawPalette_GetEntries (lpwd->dd.lpDDPal, 0, lpwd->loColor,
	lpwd->hiColor - lpwd->loColor, lppe + lpwd->loColor) == DD_OK) {
        ; /* we're all done here */
    } else {
        /* use GDI: */
        HDC hdc = GetDisplayDC (lpwd->lpszDisplayDevice);
        GetSystemPaletteEntries (hdc, lpwd->loColor, lpwd->hiColor, lppe);
        DeleteDC (hdc);
    }
    
    /* check if our colors are still there: */
    lppe2 = lpwd->lgplDefaultPalette.palPalEntry;
    for (i=lpwd->loColor; i<lpwd->hiColor; i++)
        if (lppe [i].peGreen != lppe2 [i].peGreen ||
            lppe [i].peBlue  != lppe2 [i].peBlue  ||
            lppe [i].peRed   != lppe2 [i].peRed) {
            break;
        }
	return i == lpwd->hiColor;
}


/*
* Handles Windows palette change messages.
* Use:
*  LRESULT WinDraw2_OnPaletteChange (LPWINDRAW lpwd, HWND hwnd, UINT Message);
* Input:
*  lpwd - pointer to a WINDRAW structure we work with
*  hwnd - with WM_PALETTECHANGED: identifies a window that CAUSED the
*         palette to change; window that received a message otherwise
*  Message - either WM_QUERYNEWPALETTE or WM_PALETTECHANGED
* Returns:
*  TRUE, if we do realise our palette; FALSE, otherwise.
* Notes:
*  If our window is foreground application then we should get first
*  choice of colors in the system palette entries.
*  We get best performance when our logical palette includes the
*  standard VGA colors (at the beginning and end) otherwise GDI may have
*  to map from our palette to the device palette while drawing.
*/
LRESULT WinDraw2_OnPaletteChange (LPWINDRAW lpwd, HWND hwnd, UINT Message)
{
    if (lpwd && (lpwd->fMode & WINDRAW_OPENED) && hwnd == lpwd->hWnd && 
       (Message == WM_QUERYNEWPALETTE || Message == WM_PALETTECHANGED))
    {
        if (LoadPalette(lpwd))
        {
            /* check if we are using DirectDraw: */
            if (lpwd->fMode & WINDRAW_DIRECTDRAW) 
            {
                if (FAILED(CreateDirectDrawPalette(lpwd, lpwd->dd.lpDDSPrimary)))
                    return 0;
            }

            if (lpwd->m_pSurfaceList)
            {
                for(CHXSimpleList::Iterator i = lpwd->m_pSurfaceList->Begin(); i!= lpwd->m_pSurfaceList->End(); ++i)
                {
                    LPWINDRAWSURFACE lpwds = (LPWINDRAWSURFACE) *i;
                    if (lpwds)
                    {
                        if (lpwds->fMode & WINDRAWSURFACE_DIRECTDRAW)
                        {
                            CreateDirectDrawPalette(lpwd, lpwds->dd.lpDDSurface);
                            CreateDirectDrawPalette(lpwd, lpwds->dd.lpDDBackBuffer);
                        }
                        else
                        {
                            HBITMAP hOldBitmap;
                            for(int i = 0; i<(int)lpwds->dwBackBufferCount; i++)
                            {
                                if (lpwds->gdi.lpGDIBackBuffer[i])
                                {
                                    hOldBitmap = (HBITMAP) SelectObject (lpwd->gdi.hMemoryDC, lpwds->gdi.lpGDIBackBuffer[i]->hBitMap);
                                    SetDIBColorTable(lpwd->gdi.hMemoryDC, 0, nSystemColors, SystemPaletteRGB);
                                    SelectObject(lpwd->gdi.hMemoryDC, hOldBitmap);
                                }
                            }
                        }
                    }
                }
                return (LRESULT) 1;
            }
        }
    }
    return 0;
}

/*
* When the window size changes we adjust our WINDRAW variables that
* contain the dimensions of the client rectangle for our window so
* that we come to render an image we will know whether to stretch.
*/
LRESULT WinDraw2_OnSize (LPWINDRAW lpwd, DWORD dwWidth, DWORD dwHeight)
{
    /* check parameters: */
    if (lpwd == NULL)
        return (LRESULT) 0;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?