⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gdi.c

📁 深圳市微逻辑电子有限公司 巨果&#8226 Kingmos&reg 系统核心
💻 C
📖 第 1 页 / 共 5 页
字号:
/******************************************************
Copyright(c) 版权所有,1998-2005微逻辑。保留所有权利。
******************************************************/


/*****************************************************
文件说明:图形设备界面模块
版本号:3.0.0
开发时期:1998
作者:李林
修改记录:
	 2004-09-15,DrawText 的下画线 画在了上面
     2004-05-21, 增加 StretchBlt
	 2004-05-10: 增加 TransparentBlt
     2003-09-24: DoExtSelectClipRgn 没有对expose区域做处理
     2003-09-13, SelectClipRgn( hdc, NULL ) mean valid the hdc default display surface
     2003-09-13, TA_CENTER aligned horizontally not vertizontally
     2003-09-06: LN, 在BRUSH & PEN结构增加 ->clrRef 成员
     2003-07-22, SelectClipRgn( hdc, hrgn ), 当 hrgn==NULL时,清空 region
     2003-07-22: DeleteDC( ... ) 不用 删掉 hBitmap, hBrush, hPen, ...
     2003-07-14: 增加Arc 功能 和 GDCDATA-> arcMode 成员
     2003-06-06: _GDCDATA  加入 OBJLIST   obj,取代objType和ulOwner
     2003-05-14 : CreateBitmap 为避免Heap的碎片化 对bitmap,当其所用缓存大小 大于 某大小时, 用VirtualAlloc
     2003-05-06 : 
	    1.LN 当SetBkMode( TRANSPARENT ) 并且 调用Rectangle 
	       (用WHITE_BRUSH)有错误
		2.增加对 FillRect( hdc, (COLOR_WINDOW+1) )的支持

******************************************************/

#include <eframe.h>
#include <efile.h>
#include <eassert.h>
#include <enls.h>
#include <eapisrv.h>
#include <gwmeobj.h>
#include <gdc.h>
#include <bheap.h>
#include <epwin.h>
#include <eprgn.h>
#include <winsrv.h>
#include <gdisrv.h>


#define XOFFSET( lpdc ) ((lpdc)->deviceOrg.x + (lpdc)->viewportOrg.x - (lpdc)->windowOrg.x)
#define YOFFSET( lpdc ) ((lpdc)->deviceOrg.y + (lpdc)->viewportOrg.y - (lpdc)->windowOrg.y)
#define WIDTH_LEFT( w ) ( (w) >> 1 )
#define WIDTH_TOP( w ) ( (w) >> 1 )
#define WIDTH_RIGHT( w ) ( (w) - ((w) >> 1) - 1 )
#define WIDTH_BOTTOM( w ) ( (w) - ((w) >> 1) - 1 )
#define ABS( x ) ( (x) >= 0 ? (x) : -(x) )

typedef struct __FILLRGN
{
    const _RECTNODE FAR* lprNodes;
    RECT rect;
}_FILLRGN;
typedef void ( * LPFILLFUN )( _LPCDISPLAYDRV lpDispDrv, _LPBLKBITBLT lpFillData, _FILLRGN * lpFillRgn );


#define _MAX_GDIOBJECT_NUM 10
static _GDCDATA * lpSysDC;//[_MAX_GDIOBJECT_NUM];

static CRITICAL_SECTION csDCList;
static LPOBJLIST lpDCObjList = NULL;
static HANDLE hSempore = NULL;
static int cwEllipsis;

_LPBITMAPDATA _GetHBITMAPPtr( HBITMAP );
_LPBRUSHDATA _GetHBRUSHPtr( HBRUSH hBrush );
BOOL ReleasePaintDC( HWND hWnd, HDC hdc );


extern HGDIOBJ WINAPI OEM_GetStockObject( int fObject );

static BOOL _DrawLine( _LPCDISPLAYDRV lpDispDrv, _LPRECTNODE lprn, _LINEDATA * lpLine, int x0, int y0, int x1, int y1 );
static void _FillTransparentRgn( _LPCDISPLAYDRV lpDispDrv, _LPBLKBITBLT lpFillData, _FILLRGN * lpFillRgn );
static void _FillRgn( _LPCDISPLAYDRV lpDispDrv, _LPBLKBITBLT lpFillData, _FILLRGN * lpFillRgn );
static int DoExtSelectClipRgn( HDC hdc, HRGN hrgn, int mode );

// **************************************************
// 声明:BOOL _InitialGdi( void )
// 参数:
// 	无
// 返回值:
//	假入成功,返回TRUE;否则,返回FALSE
// 功能描述:
//	初始化GDI	
// 引用: 
//	当GWME系统初始化时,回调用该函数
// ************************************************

BOOL _InitialGdi( void )
{
	int i;
	HFONT hFont;
    _LPFONT lpFont;
    InitializeCriticalSection( &csDCList );
	csDCList.lpcsName = "CS-GDC";

	lpSysDC = malloc( sizeof(_GDCDATA) * _MAX_GDIOBJECT_NUM );
	if( lpSysDC )
	{
		for( i = 0; i < _MAX_GDIOBJECT_NUM; i++ )
		{
			lpSysDC[i].obj.objType = OBJ_NULL;
		}
	}
	hFont = OEM_GetStockObject(SYSTEM_FONT);//系统默认的字体
	lpFont = _GetHFONTPtr( hFont );
	cwEllipsis = lpFont->lpDriver->lpWordWidth( lpFont->handle, ' ' );
	//初始化信号量
	hSempore = CreateSemaphore( NULL, _MAX_GDIOBJECT_NUM, _MAX_GDIOBJECT_NUM, NULL ); 
	return TRUE;
}

// **************************************************
// 声明:void _DeInitialGdi( void )
// 参数:
//    无
// 返回值:
//	无
// 功能描述:
//	关闭GDI	
// 引用: 
//	与_InitialGdi对应,该函数释放已分配的资源
// ************************************************

void _DeInitialGdi( void )
{

	CloseHandle( hSempore );
	DeleteCriticalSection( &csDCList );
}

// **************************************************
// 声明:_LPCDISPLAYDRV GetDisplayDeviceDriver( _LPBITMAPDATA lpBitmap )
// 参数:
// 	IN lpBitmap - _BITMAPDATA结构指针
// 返回值:
//	假入成功,返回显示驱动程序接口;否则,返回NULL
// 功能描述:
//	得到一个兼容显示面的图形驱动程序接口
// 引用: 
//	
// ************************************************

_LPCDISPLAYDRV GetDisplayDeviceDriver( _LPBITMAPDATA lpBitmap )
{
	_LPCDISPLAYDRV lpdd = NULL;

	if( lpBitmap &&
		lpBitmap->bmPlanes == 1 )
	{
		if( lpBitmap->bmBitsPixel == lpDisplayBitmap->bmBitsPixel )
			lpdd = lpDrvDisplayDefault;
#ifdef HAVE_GDC_1BPP
		else if( lpBitmap->bmBitsPixel == 1 )
			lpdd = &_drvDisplay1BPP;
#endif
#ifdef HAVE_GDC_4BPP
		else if( lpBitmap->bmBitsPixel == 4 )
			lpdd = &_drvDisplay4BPP;
#endif
#ifdef HAVE_GDC_8BPP
		else if( lpBitmap->bmBitsPixel == 8 ) //
			lpdd = &_drvDisplay8BPP;
#endif
#ifdef HAVE_GDC_16BPP
		else if( lpBitmap->bmBitsPixel == 16 )  //
			lpdd = &_drvDisplay16BPP;
#endif
#ifdef HAVE_GDC_32BPP
		else if( lpBitmap->bmBitsPixel == 32 )  //
			lpdd = &_drvDisplay32BPP;
#endif
#ifdef HAVE_GDC_24BPP
		else if( lpBitmap->bmBitsPixel == 24 )  
			lpdd = &_drvDisplay24BPP;
#endif
	}
	return lpdd;
}

// **************************************************
// 声明:static VOID _CheckGDCData( void )
// 参数:
// 	无 
// 返回值:
//	 无
// 功能描述:
//	检查DC
// 引用: 
//	
// ************************************************

static VOID _CheckGDCData( void )
{
	int i;
	_LPGDCDATA p = NULL;

	// 申请一个系统DC资源
	p = lpSysDC;
    for( i = 0; i < _MAX_GDIOBJECT_NUM; i++, p++ )
	{
		if( p->hwnd )
		{
			_LPWINDATA lpws;
		    //由窗口句柄得到其指针对象
			lpws = _GetHWNDPtr( p->hwnd );
			if( lpws )
			{
				DWORD dwOldPerm = SetProcPermissions( ~0 );  //得到对进程的存取权限
				RETAILMSG( 1, ( "_CheckGDCData: win=%s,class=%s,flags=0x%x.\r\n", lpws->lpWinText, lpws->lpClass->wc.lpszClassName, p->uiFlags ) );
				SetProcPermissions( dwOldPerm );  //得到对进程的存取权限
			}
		}
		else
		{
			RETAILMSG( 1, ( "_CheckGDCData: null window,objType=0x%x,flags=0x%x.\r\n", p->obj.objType, p->uiFlags ) );
		}
	}
}

// **************************************************
// 声明:static _LPGDCDATA _AllocGDCData( void )
// 参数:
// 	无 
// 返回值:
//	 假入成功,返回_GDCDATA结构指针;否则,返回NULL
// 功能描述:
//	从系统保留的DC里分配一个DC数据结构
// 引用: 
//	
// ************************************************
#define DEBUG_AllocGDCData 0
static _LPGDCDATA _AllocGDCData( void )
{
    int i, count;
	_LPGDCDATA p = NULL;

	// 申请一个系统DC资源信号量,如果申请不到,则循环申请20次
	// 我应该用更好的办法去做该功能。。。。
	count = 0;  
	while( count < 20 )
	{
		if( WaitForSingleObject( hSempore, 100 ) == WAIT_OBJECT_0 )
			break;
		WARNMSG( DEBUG_AllocGDCData, (TEXT("_AllocGDCData:try get dc(%d)\r\n"), count ) );
		count++;
	}

	if( count == 20 )
	{	//没有得到资源,通常是系统有什么错误。
		WARNMSG( DEBUG_AllocGDCData, (TEXT("_AllocGDCData:no enough DC solt, thread=0x%x\r\n"), GetCurrentThreadId() ) );
		_CheckGDCData();
		return NULL;
	}

	// 申请一个系统DC资源
	count = 20;	//试20次
	while( count-- )
	{
		p = lpSysDC;
		for( i = 0; i < _MAX_GDIOBJECT_NUM; i++, p++ )
		{
			if( p->obj.objType == OBJ_NULL &&
				Interlock_TestExchange( (LPLONG)&p->obj.objType, OBJ_NULL, OBJ_DC ) == OBJ_NULL )
			{
				p->obj.ulOwner = (ULONG)GetCallerProcess();
				return p;
			}
		}
	}
	
	// 不应该到这里
	ASSERT( 0 );
	ERRORMSG( DEBUG_AllocGDCData, (TEXT("error in _AllocGDCData: undef error!.\r\n") ) );	

	return NULL;
}

// **************************************************
// 声明:int UpdateDCState( UINT uiState )
// 参数:
// 	IN uiState - 
// 返回值:
//	返回1;
// 功能描述:
//	更新DC状态
// 引用: 
//	当窗口的Z序、大小改变并且窗口当前有正在使用的DC时,该DC对应的
//    窗口的内容(大小、裁剪区域)也虽之改变。这里就是告诉DC去重新更新
//	相关内容
// ************************************************

int UpdateDCState( UINT uiState )
{
    int i;
	_LPGDCDATA lpdc = lpSysDC;

    for( i = 0; i < _MAX_GDIOBJECT_NUM; i++, lpdc++ )
    {		
        if( lpdc->obj.objType != OBJ_NULL &&
			lpdc->hwnd )
        {   
			Interlock_TestExchange( (LPLONG)&lpdc->uiState, 0, 1 );
        }
    }
	return 1;
}

// **************************************************
// 声明:static BOOL CALLBACK DelMemDCObj( LPOBJLIST lpObj, LPARAM lParam )
// 参数:
// 	IN lpObj - _GDCDATA对象
// 返回值:
//	假入成功,返回TRUE;否则,返回FALSE
// 功能描述:
//	删除一个内存DC对象
// 引用: 
//	
// ************************************************

static BOOL CALLBACK DelMemDCObj( LPOBJLIST lpObj, LPARAM lParam )
{
	_LPGDCDATA lpdc = (_LPGDCDATA)lpObj;

    ASSERT( lpObj->objType == OBJ_MEMDC );

    WinGdi_DeleteObject( lpdc->hrgn );
    lpdc->obj.objType = OBJ_NULL;

    BlockHeap_Free( hgwmeBlockHeap, 0, lpdc, sizeof(_GDCDATA) );
    
	return TRUE;

}

// **************************************************
// 声明:BOOL WINAPI WinGdi_DeleteDC( HDC hdc )
// 参数:
// 	IN hdc - DC句柄
// 返回值:
//	假入成功,返回TRUE;否则,返回FALSE
// 功能描述:
//	删除设备对象。你不能删除用GetDC得到的hdc, 你能用ReleaseDC去释放GetDC得到的hdc
// 引用: 
//	系统API
// ************************************************

BOOL WINAPI WinGdi_DeleteDC( HDC hdc )
{
    _LPGDCDATA lpdc = _GetHDCPtr( hdc );

    if( lpdc && lpdc->obj.objType == OBJ_MEMDC )  // 合法吗?
    {
	    EnterCriticalSection( &csDCList );  //进入互斥段
	    ObjList_Remove( &lpDCObjList, &lpdc->obj );  // 从链表移出
	    LeaveCriticalSection( &csDCList );  //离开互斥段

		return DelMemDCObj( &lpdc->obj, 0 );//释放
    }
    else
    {
    	WARNMSG( 1, ( "error at WinGdi_DeleteDC: invalid hdc(0x%x).\r\n", hdc ) );
        return FALSE;
    }
}

// **************************************************
// 声明:static BOOL DelSysDC( _LPGDCDATA lpdc )
// 参数:
// 	IN lpdc - _GDCDATA结构指针
// 返回值:
//	假入成功,返回TRUE;否则,返回FALSE
// 功能描述:
//	删除DC,这里的DC是指用BeginPaint 或 GetDC 或 GetDCEx得到的
// 引用: 
//	
// ************************************************

static BOOL DelSysDC( _LPGDCDATA lpdc )
{
	WinGdi_DeleteObject( lpdc->hrgn );

	lpdc->uiState = 0; 
	lpdc->obj.ulOwner = 0;
	Interlock_Exchange( (LPLONG)&lpdc->obj.objType, OBJ_NULL );
	ReleaseSemaphore( hSempore, 1, NULL );  // 释放一个DC资源(信号量)
	return TRUE;
}

// **************************************************
// 声明:BOOL ReleasePaintDC( HWND hWnd, HDC hdc )
// 参数:
//	IN hWnd - 窗口句柄
//	IN hdc - DC句柄
// 返回值:
//	假入成功,返回TRUE;否则,返回FALSE
// 功能描述:

⌨️ 快捷键说明

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