📄 gdi.c
字号:
// local clip region and global clip region.
// if the global clip region has a new age,
// this function empty effective clip region first,
// and then intersect local clip region and global clip region.
BOOL dc_GenerateECRgn(PDC pdc, BOOL fForce)
{
RECT rc, rcInter;
PCLIPRECT pcr, pgcr;
PCONTROL pCtrl;
// is global clip region is empty?
if ((!fForce) && (!dc_IsVisible (pdc)))
return FALSE;
// need regenerate?
if (fForce || (pdc->oldage != pdc->pGCRInfo->age)) {
EmptyClipRgn (&pdc->ecrgn);
pcr = pdc->lcrgn.head;
while (pcr) {
rc = pcr->rc;
coor_LP2SP (pdc, &rc.left, &rc.top);
coor_LP2SP (pdc, &rc.right, &rc.bottom);
pgcr = pdc->pGCRInfo->crgn.head;
while (pgcr) {
if (IntersectRect (&rcInter, &rc, &pgcr->rc))
AddClipRect (&pdc->ecrgn, &rcInter);
pgcr = pgcr->next;
}
pcr = pcr->next;
}
if (pdc->lcrgn.head == NULL)
ClipRgnCopy (&pdc->ecrgn, &pdc->pGCRInfo->crgn);
// update the DevRC;
if (pdc->bIsClient)
WndClientRect (pdc->hwnd, &pdc->DevRC);
else
WndRect (pdc->hwnd, &pdc->DevRC);
IntersectClipRect (&pdc->ecrgn, &pdc->DevRC);
pCtrl = Control (pdc->hwnd);
if (pCtrl && !(pCtrl->dwExStyle & WS_EX_CTRLASMAINWIN))
RestrictControlECRGN (&pdc->ecrgn, pCtrl);
pdc->oldage = pdc->pGCRInfo->age;
}
return TRUE;
}
// This function init DC.
// set the default parameters.
static void dc_InitDC(PDC pdc, HWND hWnd, BOOL bIsClient)
{
PCONTROL pCtrl;
pdc->hwnd = hWnd;
pdc->gc = PHYSICALGC;
pdc->bkcolor = PIXEL_lightwhite;
pdc->bkmode = 0;
pdc->brushcolor = PIXEL_lightwhite;
pdc->pencolor = PIXEL_black;
pdc->CurPenPos.x = pdc->CurPenPos.y = 0;
pdc->textcolor = PIXEL_black;
if (!(pdc->pLogFont = GetWindowFont (hWnd)))
pdc->pLogFont = GetSystemFont (SYSLOGFONT_WCHAR_DEF);
pdc->tabstop = 8;
pdc->CurTextPos.x = pdc->CurTextPos.y = 0;
pdc->cExtra = pdc->alExtra = pdc->blExtra = 0;
pdc->mapmode = MM_TEXT;
pdc->ViewOrig.x = pdc->ViewOrig.y = 0;
pdc->ViewExtent.x = pdc->ViewExtent.y = 1;
pdc->WindowOrig.x = pdc->WindowOrig.y = 0;
pdc->WindowExtent.x = pdc->WindowExtent.y = 1;
// assume that the local clip region is empty.
// Get global clip region info and generate effective clip region.
pdc->pGCRInfo = GetGCRgnInfo (hWnd);
pthread_mutex_lock (&pdc->pGCRInfo->lock);
pdc->oldage = pdc->pGCRInfo->age;
ClipRgnCopy (&pdc->ecrgn, &pdc->pGCRInfo->crgn);
if (bIsClient)
WndClientRect (pdc->hwnd, &pdc->DevRC);
else
WndRect (pdc->hwnd, &pdc->DevRC);
pdc->bIsClient = bIsClient;
if (bIsClient)
IntersectClipRect (&pdc->ecrgn, &pdc->DevRC);
pCtrl = Control (pdc->hwnd);
if (pCtrl && !(pCtrl->dwExStyle & WS_EX_CTRLASMAINWIN))
RestrictControlECRGN (&pdc->ecrgn, pCtrl);
pthread_mutex_unlock (&pdc->pGCRInfo->lock);
}
static void dc_Init_ScreenDC (void)
{
__mg_screen_dc.DataType = TYPE_HDC;
__mg_screen_dc.DCType = TYPE_SCRDC;
__mg_screen_dc.hwnd = 0;
__mg_screen_dc.gc = PHYSICALGC;
__mg_screen_dc.bkcolor = PIXEL_lightwhite;
__mg_screen_dc.bkmode = 0;
__mg_screen_dc.brushcolor = PIXEL_lightwhite;
__mg_screen_dc.pencolor = PIXEL_black;
__mg_screen_dc.CurPenPos.x = __mg_screen_dc.CurPenPos.y = 0;
__mg_screen_dc.textcolor = PIXEL_black;
__mg_screen_dc.pLogFont = GetSystemFont (SYSLOGFONT_WCHAR_DEF);
__mg_screen_dc.tabstop = 8;
__mg_screen_dc.CurTextPos.x = __mg_screen_dc.CurTextPos.y = 0;
__mg_screen_dc.cExtra = __mg_screen_dc.alExtra = __mg_screen_dc.blExtra = 0;
__mg_screen_dc.ViewOrig.x = __mg_screen_dc.ViewOrig.y = 0;
__mg_screen_dc.ViewExtent.x = __mg_screen_dc.ViewExtent.y = 1;
__mg_screen_dc.WindowOrig.x = __mg_screen_dc.WindowOrig.y = 0;
__mg_screen_dc.WindowExtent.x = __mg_screen_dc.WindowExtent.y = 1;
__mg_screen_dc.bIsClient = FALSE;
// init local clip region
InitClipRgn (&__mg_screen_dc.lcrgn, &sg_FreeClipRectList);
// init effective clip region
InitClipRgn (&__mg_screen_dc.ecrgn, &sg_FreeClipRectList);
// init global clip region information
__mg_screen_dc.pGCRInfo = NULL;
__mg_screen_dc.oldage = 0;
__mg_screen_dc.DevRC.left = 0;
__mg_screen_dc.DevRC.top = 0;
__mg_screen_dc.DevRC.right = WIDTHOFPHYGC - 1;
__mg_screen_dc.DevRC.bottom = HEIGHTOFPHYGC - 1;
// Set local clip region and effetive clip region to the screen.
SetClipRgn (&__mg_screen_dc.lcrgn, &__mg_screen_dc.DevRC);
SetClipRgn (&__mg_screen_dc.ecrgn, &__mg_screen_dc.DevRC);
}
/*
* Function: HDC GUIAPI GetClientDC(HWND hWnd)
* This function get the specified window client's DC.
* Parameter:
* HWND hWnd: The window, 0 for screen.
* Return:
* The handle of wanted DC.
*/
HDC GUIAPI GetClientDC(HWND hWnd)
{
int i;
pthread_mutex_lock (&dcslot);
for (i = 0; i < DCSLOTNUMBER; i++) {
if (!DCSlot[i].inuse) {
DCSlot[i].inuse = TRUE;
DCSlot[i].DataType = TYPE_HDC;
DCSlot[i].DCType = TYPE_GENDC;
break;
}
}
pthread_mutex_unlock (&dcslot);
if (i >= DCSLOTNUMBER)
return HDC_SCREEN;
dc_InitDC (DCSlot + i, hWnd, TRUE);
return (HDC) (DCSlot + i);
}
/*
* Function: HDC GUIAPI GetDC(HWND hWnd)
* This function get the specified window's DC.
* Parameter:
* HWND hWnd: The window, 0 for screen.
* Return:
* The handle of wanted DC.
*/
HDC GUIAPI GetDC(HWND hWnd)
{
int i;
// allocate an empty dc slot exclusively
pthread_mutex_lock (&dcslot);
for(i = 0; i < DCSLOTNUMBER; i++) {
if(!DCSlot[i].inuse) {
DCSlot[i].inuse = TRUE;
DCSlot[i].DataType = TYPE_HDC;
DCSlot[i].DCType = TYPE_GENDC;
break;
}
}
pthread_mutex_unlock(&dcslot);
if (i >= DCSLOTNUMBER)
return HDC_SCREEN;
dc_InitDC(DCSlot + i, hWnd, FALSE);
return (HDC)(DCSlot + i);
}
/*
* Function: void GUIAPI ReleaseDC(HDC hDC)
* This function release the specified DC.
* Parameter:
* HDC hDC: The DC handle want to release.
* Return:
* None.
*/
void GUIAPI ReleaseDC (HDC hDC)
{
PMAINWIN pWin;
PDC pdc;
PCONTROL pCtrl;
pdc = dc_HDC2PDC(hDC);
EmptyClipRgn (&pdc->lcrgn);
pWin = (PMAINWIN)(pdc->hwnd);
if (pWin && pWin->privCDC == hDC) {
/* for private DC, we reset the clip region info. */
pthread_mutex_lock (&pdc->pGCRInfo->lock);
pdc->oldage = pdc->pGCRInfo->age;
ClipRgnCopy (&pdc->ecrgn, &pdc->pGCRInfo->crgn);
if (pdc->bIsClient)
WndClientRect (pdc->hwnd, &pdc->DevRC);
else
WndRect (pdc->hwnd, &pdc->DevRC);
IntersectClipRect (&pdc->ecrgn, &pdc->DevRC);
pCtrl = Control (pdc->hwnd);
if (pCtrl && !(pCtrl->dwExStyle & WS_EX_CTRLASMAINWIN))
RestrictControlECRGN (&pdc->ecrgn, pCtrl);
pthread_mutex_unlock (&pdc->pGCRInfo->lock);
}
else {
EmptyClipRgn (&pdc->ecrgn);
pdc->pGCRInfo = NULL;
pdc->oldage = 0;
pthread_mutex_lock (&dcslot);
pdc->inuse = FALSE;
pthread_mutex_unlock(&dcslot);
}
}
/*
* Function: HDC GUIAPI CreateCompatibleDC (HDC hdc)
* This function create a memory dc, which is compatible
* with specified hdc.
* Parameters:
* HDC hdc: the specified DC handle.
* Return:
* None.
*/
HDC GUIAPI CreateCompatibleDC(HDC hdc)
{
GAL_GC gc;
PDC pdc;
PDC pMemDC = NULL;
pdc = dc_HDC2PDC(hdc);
if (!(pMemDC = malloc (sizeof(DC)))) return HDC_INVALID;
pthread_mutex_lock (&__mg_gdilock);
if (GAL_AllocateGC (pdc->gc, RECTW (pdc->DevRC), RECTH (pdc->DevRC),
GAL_BytesPerPixel (pdc->gc), &gc) != 0) {
pthread_mutex_unlock (&__mg_gdilock);
return HDC_INVALID;
}
pthread_mutex_unlock (&__mg_gdilock);
memcpy (pMemDC, pdc, sizeof(DC));
pMemDC->DataType = TYPE_HDC;
pMemDC->DCType = TYPE_MEMDC;
pMemDC->inuse = TRUE;
pMemDC->gc = gc;
// clip region info
InitClipRgn (&pMemDC->lcrgn, &sg_FreeClipRectList);
InitClipRgn (&pMemDC->ecrgn, &sg_FreeClipRectList);
pMemDC->pGCRInfo = NULL;
pMemDC->oldage = 0;
pMemDC->DevRC.left = 0;
pMemDC->DevRC.top = 0;
pMemDC->DevRC.right = RECTW(pdc->DevRC);
pMemDC->DevRC.bottom = RECTH(pdc->DevRC);
SetClipRgn (&pMemDC->ecrgn, &pMemDC->DevRC);
return (HDC)pMemDC;
}
/*
* Function: DeleteCompatibleDC (HDC hdc)
* This function delete the memory DC, and free the associated memory.
* Parameters:
* HDC hdc: the DC handle want to delete.
* Return:
* FALSE: the specified HDC is not a valid memory DC.
* TRUE: deleted.
*/
void GUIAPI DeleteCompatibleDC(HDC hdc)
{
PDC pMemDC;
pMemDC = dc_HDC2PDC(hdc);
// free gl resource
GAL_FreeGC (pMemDC->gc);
// free clip region info
EmptyClipRgn (&pMemDC->lcrgn);
EmptyClipRgn (&pMemDC->ecrgn);
// free DC slot
free (pMemDC);
}
HDC GUIAPI CreatePrivateDC(HWND hwnd)
{
PDC pdc;
if (!(pdc = malloc (sizeof(DC)))) return HDC_INVALID;
InitClipRgn (&pdc->lcrgn, &sg_FreeClipRectList);
InitClipRgn (&pdc->ecrgn, &sg_FreeClipRectList);
pdc->inuse = TRUE;
pdc->DataType = TYPE_HDC;
pdc->DCType = TYPE_GENDC;
dc_InitDC(pdc, hwnd, FALSE);
return (HDC)(pdc);
}
HDC GUIAPI CreatePrivateClientDC(HWND hwnd)
{
PDC pdc;
if (!(pdc = malloc (sizeof(DC)))) return HDC_INVALID;
InitClipRgn (&pdc->lcrgn, &sg_FreeClipRectList);
InitClipRgn (&pdc->ecrgn, &sg_FreeClipRectList);
pdc->inuse = TRUE;
pdc->DataType = TYPE_HDC;
pdc->DCType = TYPE_GENDC;
dc_InitDC(pdc, hwnd, TRUE);
return (HDC)(pdc);
}
void GUIAPI DeletePrivateDC(HDC hdc)
{
PDC pdc;
pdc = (PDC)hdc;
EmptyClipRgn (&pdc->lcrgn);
EmptyClipRgn (&pdc->ecrgn);
free (pdc);
}
HDC GUIAPI GetPrivateClientDC (HWND hwnd)
{
PMAINWIN pWin = (PMAINWIN)hwnd;
return pWin->privCDC;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -