Click here to Skip to main content
15,891,136 members
Articles / Programming Languages / ASM

Driver Development Part 6: Introduction to Display Drivers

Rate me:
Please Sign up or sign in to vote.
4.94/5 (82 votes)
29 Jan 200620 min read 619.4K   8.3K   363  
Introduction to the Windows display driver model.
/***********************************************************************
 * GDI.C
 *  
 *    API for GDI
 *
 *
 * Toby Opferman Copyright (c) 2003
 *
 ***********************************************************************/
 

                                                                     
#include <windows.h>
#include <stdarg.h>
#include <stdlib.h>
#include <stdio.h>
#include "gdi.h"


 /***********************************************************************
  * Macros
  ***********************************************************************/
#define COLOR_GOTO_COLOR(x, y, z) if(x > y) { x--; z = FALSE; } else if(x < y) { x++; z = FALSE; } 


 /***********************************************************************
  * Internal Structures
  ***********************************************************************/
  typedef struct {

      HWND hWnd;
      HDC hDoubleBuffer;
      HDC hDoubleBufferWorker;
      BITMAPINFO BitmapInfo;
      HBITMAP hCompatBitmap;
      HBITMAP hOldCompatBitmap;
      HGDIOBJ hOldBitMap;
      HBITMAP hDBBitMap;
      UCHAR *pBuffer;
      DWORD dwScreenX;
      DWORD dwScreenY;
      PALETTEENTRY VirtualPalette[256];
      DWORD dwOptimizedPaletteLookUp[256];
      CRITICAL_SECTION csRepaintBlock;

  } GDI, *PGDI;




 /***********************************************************************
  * GDI_Init
  *  
  *    Initialize Full Screen
  *
  * Parameters
  *     Window  Handle
  * 
  * Return Value
  *     Handle To Cubix
  *
  ***********************************************************************/
HGDI WINAPI GDI_Init(HWND hWnd, UINT dwScreenX, UINT dwScreenY)
{
    PGDI pGDI = NULL;
    HDC hDC;
    int iScreenY = dwScreenY;

    /* Bitmaps Are Upside Down, Need To Negate */
    iScreenY = -iScreenY;

    if(pGDI = (PGDI)LocalAlloc(LMEM_ZEROINIT, sizeof(GDI)))
    {
        
        InitializeCriticalSection(&pGDI->csRepaintBlock);
        

        pGDI->dwScreenX = dwScreenX;
        pGDI->dwScreenY = dwScreenY;

        pGDI->BitmapInfo.bmiHeader.biSize     = sizeof(BITMAPINFOHEADER);
        pGDI->BitmapInfo.bmiHeader.biBitCount = 32;
        pGDI->BitmapInfo.bmiHeader.biWidth    = dwScreenX;
        pGDI->BitmapInfo.bmiHeader.biHeight   = iScreenY;
        pGDI->BitmapInfo.bmiHeader.biPlanes   = 1;
        pGDI->BitmapInfo.bmiHeader.biCompression = BI_RGB;

        hDC = GetDC(hWnd);

        pGDI->hDoubleBuffer = CreateCompatibleDC(hDC);
        pGDI->hDoubleBufferWorker = CreateCompatibleDC(hDC);
        pGDI->hDBBitMap  = CreateDIBSection(pGDI->hDoubleBufferWorker, &pGDI->BitmapInfo, DIB_RGB_COLORS, (VOID **)&pGDI->pBuffer, NULL, 0);
        pGDI->hCompatBitmap = CreateCompatibleBitmap(hDC, dwScreenX, dwScreenY);
        pGDI->hOldCompatBitmap = SelectObject(pGDI->hDoubleBuffer, pGDI->hCompatBitmap);
        pGDI->hOldBitMap = SelectObject(pGDI->hDoubleBufferWorker, pGDI->hDBBitMap);

        ReleaseDC(hWnd, hDC);
        
    }

    return (HGDI)pGDI;
}



 /***********************************************************************
  * GDI_UnInit
  *  
  *    UnInitialize Test Graphics
  *
  * Parameters
  *     Handle to Test
  * 
  * Return Value
  *     Nothing
  *
  ***********************************************************************/
void WINAPI GDI_UnInit(HGDI hGDI)
{
    PGDI pGDI = (PGDI)hGDI;

    if(pGDI)
    {
        LocalFree(pGDI);
    }
}


 /***********************************************************************
  * GDI_GetDC
  *  
  *    Get The Video DC
  *
  * Parameters
  *     Handle to Test
  * 
  * Return Value
  *     Nothing
  *
  ***********************************************************************/
HDC GDI_GetDC(HGDI hGDI)
{
    PGDI pGDI = (PGDI)hGDI;

    EnterCriticalSection(&pGDI->csRepaintBlock);
    return pGDI->hDoubleBuffer;
}


 /***********************************************************************
  * GDI_GetDC
  *  
  *    Get The Video DC
  *
  * Parameters
  *     Handle to Test
  * 
  * Return Value
  *     Nothing
  *
  ***********************************************************************/
void GDI_ReleaseDC(HGDI hGDI)
{
    PGDI pGDI = (PGDI)hGDI;

    LeaveCriticalSection(&pGDI->csRepaintBlock);
}

 /***********************************************************************
  * GDI_BeginPaint
  *  
  *    Get The Video Buffer
  *
  * Parameters
  *     Handle to Test
  * 
  * Return Value
  *     Nothing
  *
  ***********************************************************************/
PUCHAR WINAPI GDI_BeginPaint(HGDI hGDI)
{
   PGDI pGDI = (PGDI)hGDI;

   return pGDI->pBuffer;
}



 /***********************************************************************
  * GDI_EndPaint
  *  
  *    End Painting
  *
  * Parameters
  *     Handle to Test
  * 
  * Return Value
  *     Nothing
  *
  ***********************************************************************/
void WINAPI GDI_EndPaint(HGDI hGDI)
{
    PGDI pGDI = (PGDI)hGDI;

    EnterCriticalSection(&pGDI->csRepaintBlock);
    BitBlt(pGDI->hDoubleBuffer, 0, 0, pGDI->dwScreenX, pGDI->dwScreenY, pGDI->hDoubleBufferWorker, 0, 0, SRCCOPY);
    LeaveCriticalSection(&pGDI->csRepaintBlock);
    
}



/***********************************************************************
 * GDI_BlastBuffer
 *  
 *    Clear Video Buffer
 *
 * Parameters
 *     Video Buffer
 *
 * Return Value
 *     Nothing
 *
 ***********************************************************************/
void WINAPI GDI_BlastBuffer(HGDI hGDI, PUCHAR pBuffer)
{
   PGDI pGDI = (PGDI)hGDI;

   memcpy(pGDI->pBuffer, pBuffer, pGDI->dwScreenX*pGDI->dwScreenY*4);
}



/***********************************************************************
 * GDI_ClearVideoBuffer
 *  
 *    Clear Video Buffer
 *
 * Parameters
 *     Video Buffer
 *
 * Return Value
 *     Nothing
 *
 ***********************************************************************/
void WINAPI GDI_ClearVideoBuffer(HGDI hGDI)
{
   PGDI pGDI = (PGDI)hGDI;

   memset(pGDI->pBuffer, 0, pGDI->dwScreenX*pGDI->dwScreenY*4);
}

/***********************************************************************
 * GDI_SetPalette
 *  
 *    
 *
 * Parameters
 *     Video Buffer
 *
 * Return Value
 *     Nothing
 *
 ***********************************************************************/
void WINAPI GDI_SetPalette(HGDI hGDI, PALETTEENTRY *pPaletteEntries)
{
   PGDI pGDI = (PGDI)hGDI;
   DWORD dwIndex;

   for(dwIndex = 0; dwIndex < 256; dwIndex++)
   {
      pGDI->VirtualPalette[dwIndex].peBlue  = pPaletteEntries[dwIndex].peBlue;
      pGDI->VirtualPalette[dwIndex].peGreen = pPaletteEntries[dwIndex].peGreen;
      pGDI->VirtualPalette[dwIndex].peRed   = pPaletteEntries[dwIndex].peRed;

      pGDI->dwOptimizedPaletteLookUp[dwIndex] = pGDI->VirtualPalette[dwIndex].peBlue | (pGDI->VirtualPalette[dwIndex].peGreen<<8) | (pGDI->VirtualPalette[dwIndex].peRed<<16);
   }
}


/***********************************************************************
 * GDI_FadePalette
 *  
 *    
 *
 * Parameters
 *     Video Buffer
 *
 * Return Value
 *     Nothing
 *
 ***********************************************************************/
BOOL WINAPI GDI_FadePalette(HGDI hGDI)
{
   PGDI pGDI = (PGDI)hGDI;
   BOOL bFaded = TRUE;
   DWORD dwIndex;

   for(dwIndex = 0; dwIndex < 256; dwIndex++)
   {
      COLOR_GOTO_COLOR(pGDI->VirtualPalette[dwIndex].peBlue, 0, bFaded);
      COLOR_GOTO_COLOR(pGDI->VirtualPalette[dwIndex].peGreen, 0, bFaded);
      COLOR_GOTO_COLOR(pGDI->VirtualPalette[dwIndex].peRed, 0, bFaded);

      pGDI->dwOptimizedPaletteLookUp[dwIndex] = pGDI->VirtualPalette[dwIndex].peBlue | (pGDI->VirtualPalette[dwIndex].peGreen<<8) | (pGDI->VirtualPalette[dwIndex].peRed<<16);
   }

   return bFaded;
}


/***********************************************************************
 * GDI_GetVPalEntry
 *  
 *    
 *
 * Parameters
 *     Video Buffer
 *
 * Return Value
 *     Nothing
 *
 ***********************************************************************/
DWORD WINAPI GDI_GetVPalEntry(HGDI hGDI, DWORD dwIndex)
{
   PGDI pGDI = (PGDI)hGDI;

   return pGDI->dwOptimizedPaletteLookUp[dwIndex];
}

/***********************************************************************
 * GDI_SetPixelUsingVPal
 *  
 *    
 *
 * Parameters
 *     Video Buffer
 *
 * Return Value
 *     Nothing
 *
 ***********************************************************************/
void WINAPI GDI_SetPixelUsingVPal(HGDI hGDI, DWORD dwIndexX, DWORD dwIndexY, DWORD dwIndex)
{
   PGDI pGDI = (PGDI)hGDI;

   memcpy(&pGDI->pBuffer[(dwIndexX*4) + (dwIndexY*pGDI->dwScreenX*4)], &pGDI->dwOptimizedPaletteLookUp[dwIndex], 4);

}



/***********************************************************************
 * DirectX_FadeToPalette
 *  
 *    
 *
 * Parameters
 *     Video Buffer
 *
 * Return Value
 *     Nothing
 *
 ***********************************************************************/
BOOL WINAPI GDI_FadeToPalette(HGDI hGDI, PALETTEENTRY *pPaletteEntries)
{
   PGDI pGDI = (PGDI)hGDI;
   BOOL bFaded = TRUE;
   DWORD dwIndex;

   for(dwIndex = 0; dwIndex < 256; dwIndex++)
   {
      COLOR_GOTO_COLOR(pGDI->VirtualPalette[dwIndex].peBlue, pPaletteEntries[dwIndex].peBlue, bFaded);
      COLOR_GOTO_COLOR(pGDI->VirtualPalette[dwIndex].peGreen, pPaletteEntries[dwIndex].peGreen, bFaded);
      COLOR_GOTO_COLOR(pGDI->VirtualPalette[dwIndex].peRed, pPaletteEntries[dwIndex].peRed, bFaded);

      pGDI->dwOptimizedPaletteLookUp[dwIndex] = pGDI->VirtualPalette[dwIndex].peBlue | (pGDI->VirtualPalette[dwIndex].peGreen<<8) | (pGDI->VirtualPalette[dwIndex].peRed<<16);
   }

   return bFaded;
}







/***********************************************************************
 * GDI_Debug
 *  
 *    Debug Shit
 *
 *    
 *
 * Parameters
 *     Debug
 *
 * Return Value
 *     Nothing
 *
 ***********************************************************************/
 void GDI_Debug(char *pszFormatString, ...)
 {
     char DebugString[256];
     va_list vl;

     va_start(vl, pszFormatString);
     vsprintf(DebugString, pszFormatString, vl);
     va_end(vl);

     OutputDebugString(DebugString);
 }





By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Engineer Intel
United States United States
Toby Opferman has worked in just about all aspects of Windows development including applications, services and drivers.

He has also played a variety of roles professionally on a wide range of projects. This has included pure researching roles, architect roles and developer roles. He also was also solely responsible for debugging traps and blue screens for a number of years.

Previously of Citrix Systems he is very experienced in the area of Terminal Services. He currently works on Operating Systems and low level architecture at Intel.

He has started a youtube channel called "Checksum Error" that focuses on software.
https://www.youtube.com/channel/UCMN9q8DbU0dnllWpVRvn7Cw

Comments and Discussions