Beispiel #1
0
CBackground::CBackground()
{
    bgSize = MakeCoord(-1,-1);
    hBgDc = NULL;
    hBgBitmap = NULL;
    hOldBitmap = NULL;
    //// Alpha blending
    //mh_MsImg32 = LoadLibrary(L"Msimg32.dll");
    //if (mh_MsImg32) {
    //	fAlphaBlend = (AlphaBlend_t)GetProcAddress(mh_MsImg32, "AlphaBlend");
    //} else {
    //	fAlphaBlend = NULL;
    //}
#ifdef __GNUC__
    HMODULE hGdi32 = GetModuleHandle(L"gdi32.dll");
    GdiAlphaBlend = (AlphaBlend_t)(hGdi32 ? GetProcAddress(hGdi32, "GdiAlphaBlend") : NULL);
#endif

    mb_NeedBgUpdate = false;
    mb_BgLastFade = false;
    mp_BkImgData = NULL;
    mn_BkImgDataMax = 0;
    mb_BkImgChanged = FALSE;
    mb_BkImgExist = /*mb_BkImgDelete =*/ FALSE;
    mp_BkEmfData = NULL;
    mn_BkEmfDataMax = 0;
    mb_BkEmfChanged = FALSE;
    mcs_BkImgData = NULL;
    mn_BkImgWidth = mn_BkImgHeight = 0;
}
Beispiel #2
0
// Helper function: support Tab-completion in cmd.exe and others
COORD FixupReadStartCursorPos(DWORD nNumberOfCharsToRead, CONSOLE_SCREEN_BUFFER_INFO& csbi, const MY_CONSOLE_READCONSOLE_CONTROL* pInputControl)
{
	COORD crStartCursorPos = csbi.dwCursorPosition;

	if (pInputControl && (pInputControl->nLength >= sizeof(*pInputControl)))
	{
		if (pInputControl->nInitialChars < nNumberOfCharsToRead)
		{
			// Part of input is already "printed" to the buffer, take it into account
			int nNewX = (int)crStartCursorPos.X - pInputControl->nInitialChars;
			int nNewY = (int)crStartCursorPos.Y;
			if (nNewX < 0)
			{
				int nRows = klMin(nNewY, (int)((-nNewX) / csbi.dwSize.X));
				if ((nRows < nNewY) && ((nNewX + (nRows * csbi.dwSize.X)) < 0))
					nRows++;
				_ASSERTE(((nNewY - nRows) >= 0) && ((nNewX + (nRows * csbi.dwSize.X)) >= 0));
				nNewX += (nRows * csbi.dwSize.X);
				nNewY -= nRows;
			}
			if (nNewX >= 0 && nNewY >= 0)
			{
				crStartCursorPos = MakeCoord(nNewX, nNewY);
				csbi.dwCursorPosition = crStartCursorPos;
			}
			else
			{
				_ASSERTE(nNewX >= 0 && nNewY >= 0);
			}
		}
	}

	return crStartCursorPos;
}
Beispiel #3
0
void TermX::Reset()
{
	AppCursorKeys = false;
	MouseButtons = 0;
	LastMousePos = MakeCoord(-1,-1);
	LastDeadCharVK = 0;
}
Beispiel #4
0
// Должна вернуть true, если данные изменились (то есть будет isForce при полной перерисовке)
bool CBackground::PrepareBackground(CVirtualConsole* pVCon, HDC&/*OUT*/ phBgDc, COORD&/*OUT*/ pbgBmpSize)
{
	if (!this)
	{
		_ASSERTE(this!=NULL);
		return false;
	}

	_ASSERTE(isMainThread() && "Must be executed in main thread");

	bool bSucceeded = true;
	bool lbForceUpdate = false;
	LONG lBgWidth = 0, lBgHeight = 0;
	BOOL lbVConImage = FALSE;

	if (gpSet->isBgPluginAllowed)
	{
		if (HasPluginBackgroundImage(&lBgWidth, &lBgHeight)
			&& lBgWidth && lBgHeight)
		{
			lbVConImage = TRUE;
		}
	}

	LONG lMaxBgWidth = 0, lMaxBgHeight = 0;
	bool bIsForeground = gpConEmu->isMeForeground(true);


	// Если плагин свой фон не подсунул
	if (!lbVConImage)
	{
		//if (mp_PluginBg)
		//{
		//	delete mp_PluginBg;
		//	mp_PluginBg = NULL;
		//}

		#ifndef APPDISTINCTBACKGROUND
		// То работаем на общих основаниях, через настройки (или AppDistinct)
		return gpSetCls->PrepareBackground(pVCon, &phBgDc, &pbgBmpSize);
		#else

		CBackgroundInfo* pBgFile = pVCon->GetBackgroundObject();
		if (!pBgFile)
		{
			_ASSERTE(FALSE && "Background object must be created in VCon");
			return false;
		}

		if (!mb_NeedBgUpdate)
		{
			if ((hBgDc == NULL)
				|| (mb_BgLastFade == bIsForeground && gpSet->isFadeInactive)
				|| (!gpSet->isFadeInactive && mb_BgLastFade))
			{
				NeedBackgroundUpdate();
			}
		}

		pBgFile->PollBackgroundFile();

		RECT rcWork = {0, 0, pVCon->GetVConWidth(), pVCon->GetVConHeight()};

		// необходимо проверить размер требуемой картинки
		// -- здесь - всегда только файловая подложка
		if ((gpSet->bgOperation == eUpLeft) || (gpSet->bgOperation == eUpRight)
			|| (gpSet->bgOperation == eDownLeft) || (gpSet->bgOperation == eDownRight)
			|| (gpSet->bgOperation == eCenter))
		{
			// MemoryDC создается всегда по размеру картинки, т.е. изменение размера окна - игнорируется
		}
		else
		{
			// Смотрим дальше
			if (gpSet->bgOperation == eStretch)
			{
				// Строго по размеру клиентской (точнее Workspace) области окна
				lMaxBgWidth = rcWork.right - rcWork.left;
				lMaxBgHeight = rcWork.bottom - rcWork.top;
			}
			else if (gpSet->bgOperation == eFit || gpSet->bgOperation == eFill)
			{
				lMaxBgWidth = rcWork.right - rcWork.left;
				lMaxBgHeight = rcWork.bottom - rcWork.top;
				// Correct aspect ratio
				const BITMAPFILEHEADER* pBgImgData = pBgFile->GetBgImgData();
				const BITMAPINFOHEADER* pBmp = pBgImgData ? (const BITMAPINFOHEADER*)(pBgImgData+1) : NULL;
				if (pBmp
					&& (rcWork.bottom - rcWork.top) > 0 && (rcWork.right - rcWork.left) > 0)
				{
					double ldVCon = (rcWork.right - rcWork.left) / (double)(rcWork.bottom - rcWork.top);
					double ldImg = pBmp->biWidth / (double)pBmp->biHeight;
					if (ldVCon > ldImg)
					{
						if (gpSet->bgOperation == eFit)
							lMaxBgWidth = (LONG)(lMaxBgHeight * ldImg);
						else
							lMaxBgHeight = (LONG)(lMaxBgWidth / ldImg);
					}
					else
					{
						if (gpSet->bgOperation == eFill)
							lMaxBgWidth = (LONG)(lMaxBgHeight * ldImg);
						else
							lMaxBgHeight = (LONG)(lMaxBgWidth / ldImg);
					}
				}
			}
			else if (gpSet->bgOperation == eTile)
			{
				// Max между клиентской (точнее Workspace) областью окна и размером текущего монитора
				// Окно может быть растянуто на несколько мониторов, т.е. размер клиентской области может быть больше
				HMONITOR hMon = MonitorFromWindow(ghWnd, MONITOR_DEFAULTTONEAREST);
				MONITORINFO mon = {sizeof(MONITORINFO)};
				GetMonitorInfo(hMon, &mon);
				//
				lMaxBgWidth = klMax(rcWork.right - rcWork.left,mon.rcMonitor.right - mon.rcMonitor.left);
				lMaxBgHeight = klMax(rcWork.bottom - rcWork.top,mon.rcMonitor.bottom - mon.rcMonitor.top);
			}

			if (bgSize.X != lMaxBgWidth || bgSize.Y != lMaxBgHeight)
				NeedBackgroundUpdate();
		}

		if (mb_NeedBgUpdate)
		{
			mb_NeedBgUpdate = false;
			lbForceUpdate = true;
			_ASSERTE(isMainThread());
			//MSectionLock SBG; SBG.Lock(&mcs_BgImgData);
			//BITMAPFILEHEADER* pImgData = mp_BgImgData;
			BackgroundOp op = (BackgroundOp)gpSet->bgOperation;
			const BITMAPFILEHEADER* pBgImgData = pBgFile->GetBgImgData();
			BOOL lbImageExist = (pBgImgData != NULL);
			//BOOL lbVConImage = FALSE;
			//LONG lBgWidth = 0, lBgHeight = 0;
			//CVirtualConsole* pVCon = gpConEmu->ActiveCon();

			////MSectionLock SBK;
			//if (apVCon && gpSet->isBgPluginAllowed)
			//{
			//	//SBK.Lock(&apVCon->csBkImgData);
			//	if (apVCon->HasBackgroundImage(&lBgWidth, &lBgHeight)
			//	        && lBgWidth && lBgHeight)
			//	{
			//		lbVConImage = lbImageExist = TRUE;
			//	}
			//}

			//mb_WasVConBgImage = lbVConImage;

			if (lbImageExist)
			{
				mb_BgLastFade = (!bIsForeground && gpSet->isFadeInactive);
				TODO("Переделать, ориентироваться только на размер картинки - неправильно");
				TODO("DoubleView - скорректировать X,Y");

				//if (lbVConImage)
				//{
				//	if (lMaxBgWidth && lMaxBgHeight)
				//	{
				//		lBgWidth = lMaxBgWidth;
				//		lBgHeight = lMaxBgHeight;
				//	}

				//	if (!mp_Bg->CreateField(lBgWidth, lBgHeight) ||
				//	        !apVCon->PutBackgroundImage(mp_Bg, 0,0, lBgWidth, lBgHeight))
				//	{
				//		delete mp_Bg;
				//		mp_Bg = NULL;
				//	}
				//}
				//else
				{
					const BITMAPINFOHEADER* pBmp = (const BITMAPINFOHEADER*)(pBgImgData+1);

					if (!lMaxBgWidth || !lMaxBgHeight)
					{
						// Сюда мы можем попасть только в случае eUpLeft/eUpRight/eDownLeft/eDownRight
						lMaxBgWidth = pBmp->biWidth;
						lMaxBgHeight = pBmp->biHeight;
					}

					//LONG lImgX = 0, lImgY = 0, lImgW = lMaxBgWidth, lImgH = lMaxBgHeight;

					//if ((gpSet->bgOperation == eFit || gpSet->bgOperation == eFill)
					//	&& (rcWork.bottom - rcWork.top) > 0 && (rcWork.right - rcWork.left) > 0)
					//{
					//	double ldVCon = (rcWork.right - rcWork.left) / (double)(rcWork.bottom - rcWork.top);
					//	double ldImg = pBmp->biWidth / (double)pBmp->biHeight;
					//	if (ldVCon > ldImg)
					//	{
					//		if (gpSet->bgOperation == eFit)
					//			lMaxBgWidth = lMaxBgHeight * ldImg;
					//		else
					//			lMaxBgHeight = lMaxBgWidth / ldImg;
					//	}
					//	else
					//	{
					//		if (gpSet->bgOperation == eFill)
					//			lMaxBgWidth = lMaxBgHeight * ldImg;
					//		else
					//			lMaxBgHeight = lMaxBgWidth / ldImg;
					//	}
					//}

					if (!CreateField(lMaxBgWidth, lMaxBgHeight) ||
						!FillBackground(pBgImgData, 0,0,lMaxBgWidth,lMaxBgHeight, op, mb_BgLastFade))
					{
						bSucceeded = false;
					}
				}
			}
			else
			{
				bSucceeded = false;
			}
		}

		pBgFile->Release();

		#endif
	}
	else
	{
		if (!mb_NeedBgUpdate)
		{
			if ((mb_BgLastFade == bIsForeground && gpSet->isFadeInactive)
				|| (!gpSet->isFadeInactive && mb_BgLastFade))
			{
				NeedBackgroundUpdate();
			}
		}

		//if (mp_PluginBg == NULL)
		//{
		//	NeedBackgroundUpdate();
		//}

		if (mb_NeedBgUpdate)
		{
			mb_NeedBgUpdate = false;
			lbForceUpdate = true;

			//if (!mp_PluginBg)
			//	mp_PluginBg = new CBackground;

			mb_BgLastFade = (!bIsForeground && gpSet->isFadeInactive);
			TODO("Переделать, ориентироваться только на размер картинки - неправильно");
			TODO("DoubleView - скорректировать X,Y");

			if (lMaxBgWidth && lMaxBgHeight)
			{
				lBgWidth = lMaxBgWidth;
				lBgHeight = lMaxBgHeight;
			}

			if (!CreateField(lBgWidth, lBgHeight) ||
				!PutPluginBackgroundImage(0,0, lBgWidth, lBgHeight))
			{
				//delete mp_PluginBg;
				//mp_PluginBg = NULL;
				bSucceeded = false;
			}
		}

		// Check if the bitmap was prepared for the current Far state
		if ((mp_BkImgData && pVCon)
			// Don't use isFilePanel here because it is `false` when any dialog is active in Panels
			&& ((!(pVCon->isEditor || pVCon->isViewer) && !(mp_BkImgData->dwDrawnPlaces & pbp_Panels))
				|| (pVCon->isEditor && !(mp_BkImgData->dwDrawnPlaces & pbp_Editor))
				|| (pVCon->isViewer && !(mp_BkImgData->dwDrawnPlaces & pbp_Viewer))
			))
		{
			lbForceUpdate = false;
			phBgDc = NULL;
			pbgBmpSize = MakeCoord(0, 0);
			goto wrap;
		}
	}

	if (bSucceeded)
	{
		phBgDc = hBgDc;
		pbgBmpSize = bgSize;
	}
	else
	{
		phBgDc = NULL;
		pbgBmpSize = MakeCoord(0,0);
	}

wrap:
	return lbForceUpdate;
}