os/kernelhwsrv/kernel/eka/drivers/edisp/emul/win32/wd_wins.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     1 // Copyright (c) 1995-2009 Nokia Corporation and/or its subsidiary(-ies).
     2 // All rights reserved.
     3 // This component and the accompanying materials are made available
     4 // under the terms of the License "Eclipse Public License v1.0"
     5 // which accompanies this distribution, and is available
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
     7 //
     8 // Initial Contributors:
     9 // Nokia Corporation - initial contribution.
    10 //
    11 // Contributors:
    12 //
    13 // Description:
    14 // e32\drivers\edisp\emul\win32\wd_wins.cpp
    15 // 
    16 //
    17 
    18 #include <e32cmn.h>
    19 #include <e32cmn_private.h>
    20 #include <emulator.h>
    21 #define WIN32_LEAN_AND_MEAN
    22 #pragma warning( disable : 4201 ) // nonstandard extension used : nameless struct/union
    23 #include <windows.h>
    24 #pragma warning( default : 4201 ) // nonstandard extension used : nameless struct/union
    25 #include "ws_std.h"
    26 
    27 // Driver for WINS platform using windows stock font
    28 
    29 #define FONTWIDTH 8
    30 #define FONTHEIGHT 12
    31 
    32 struct rgbValues{
    33 	TUint8 iRed;
    34 	TUint8 iGreen;
    35 	TUint8 iBlue;
    36 	};
    37 
    38 const TUint8 KMonoRed0=50;
    39 const TUint8 KMonoGreen0=100;
    40 const TUint8 KMonoBlue0=200;
    41 const TUint8 KMonoRed1=250;
    42 const TUint8 KMonoGreen1=250;
    43 const TUint8 KMonoBlue1=20;
    44 
    45 const TColorIndex KMonoAttributes[8]=
    46     {
    47     1,      // Normal foreground
    48     0,      // Normal background
    49     1,      // Bold foreground
    50     0,      // Bold background
    51     0,      // Inverse foreground
    52     1,      // Inverse background
    53     0,      // Highlight foreground
    54     1       // Highlight background
    55     };
    56 
    57 const TColorIndex KColor256Attributes[8]=
    58     {
    59     38,      // Normal foreground
    60     33,      // Normal background
    61     36,      // Bold foreground
    62     38,      // Bold background
    63     33,      // Inverse foreground
    64     38,      // Inverse background
    65     38,      // Highlight foreground
    66     36       // Highlight background
    67     };
    68 
    69 class CScreenDriverWins : public CScreenDriver
    70 	{
    71 	friend class CScreenDriver;
    72 public:
    73 	CScreenDriverWins();
    74 	virtual void Init(TSize &aScreenSize,TSize &aFontSize);
    75 	virtual void Blit(const TText *aBuffer,TInt aLength,const TPoint &aPosition);
    76 	virtual TBool ScrollUp(const TRect& aRect);
    77 	virtual void Clear(const TRect& aRect);
    78 
    79 	virtual void SetPixel(const TPoint& aPoint,TUint8 aColour);
    80 	virtual TInt GetPixel(const TPoint& aPoint);
    81 	virtual void SetWord(const TPoint& aPoint,TInt aWord);
    82 	virtual TInt GetWord(const TPoint& aPoint);
    83 	virtual void SetLine(const TPoint& aPoint,const TPixelLine& aPixelLine);
    84 	virtual void GetLine(const TPoint& aPoint,TPixelLine& aPixelLine);
    85 	virtual void SetPaletteEntry(TColorIndex anIndex,TUint8 aRed,TUint8 aGreen,TUint8 aBlue);
    86 	virtual void GetPaletteEntry(TColorIndex anIndex,TUint8 &aRed,TUint8 &aGreen,TUint8 &aBlue);
    87 	virtual void SetForegroundColor(TColorIndex anIndex);
    88 	virtual void SetBackgroundColor(TColorIndex anIndex);
    89 	virtual void GetAttributeColors(TColorIndex* anArray);
    90 
    91 	virtual TInt SetMode(TVideoMode aMode);
    92 
    93 	static TBool IsHankaku(const TText aCode);
    94 	virtual TPoint GraphicsPosition(const TPoint& aPosition);
    95 	virtual void ScreenBufferScrollUp(const TRect& aRect);
    96 	virtual void ScreenBufferClear(const TRect& aRect);
    97 private:
    98     TText* iScreenBuffer;
    99 
   100 private:
   101 	HFONT iFont;
   102     HDC iDc;
   103 	TSize iTextScreenSize;
   104 	TScreenInfoV01 iScreenInfo;
   105 	TVideoMode iMode;
   106 	rgbValues* iPalette; 
   107 	};
   108 
   109 
   110 TPoint CScreenDriverWins::GraphicsPosition(const TPoint& aPosition)
   111 	{
   112     TPoint pos(0,aPosition.iY*FONTHEIGHT);
   113     TText* pS=iScreenBuffer+(iTextScreenSize.iWidth*aPosition.iY);
   114     TText* pE=pS+aPosition.iX;
   115 	for (TText* pT=pS;pT<pE;++pT)
   116 		pos.iX+=IsHankaku(*pT) ? FONTWIDTH : FONTWIDTH*2;
   117     return(pos);
   118 	}
   119 
   120 TBool CScreenDriverWins::IsHankaku(const TText aCode)
   121 	{
   122 	if (aCode >= 0xff61 && aCode <= 0xff9f) 
   123 		return ETrue;	// HANKAKU KATAKANA code
   124 	if (aCode >= 0x2550 && aCode <= 0x259f)
   125 		return ETrue;	// HANKAKU Graphics code
   126 	if (aCode < 0x100)
   127         return ETrue;	// Alphanumeric codes means HANKAKU
   128 	return EFalse;
   129 	}
   130 
   131 void CScreenDriverWins::ScreenBufferScrollUp(const TRect& aRect)
   132 	{
   133 	TText* src=&iScreenBuffer[(aRect.iTl.iY+1)*iTextScreenSize.iWidth+aRect.iTl.iX];
   134 	TText* dest=&iScreenBuffer[aRect.iTl.iY*iTextScreenSize.iWidth+aRect.iTl.iX];
   135 	for (TInt j=0;j<aRect.iBr.iY-aRect.iTl.iY;++j)
   136         {
   137 		TInt r=j*iTextScreenSize.iWidth;
   138 		for (TInt i=0;i<aRect.iBr.iX-aRect.iTl.iX+1;++i)
   139             {
   140 			TInt p = r+i;
   141 			dest[p] = src[p];
   142 			}
   143 		}
   144 	}
   145 
   146 void CScreenDriverWins::ScreenBufferClear(const TRect& aRect)
   147 	{
   148 	TText* dest=&iScreenBuffer[aRect.iTl.iY*iTextScreenSize.iWidth+aRect.iTl.iX];
   149 	for (TInt j=0;j<aRect.iBr.iY-aRect.iTl.iY+1;++j)
   150         {
   151 		TInt r=j*iTextScreenSize.iWidth;
   152 		for (TInt i=0;i<aRect.iBr.iX-aRect.iTl.iX+1;++i)
   153 			dest[r+i] = 0x0020;
   154 		}
   155 	}
   156 
   157 CScreenDriverWins::CScreenDriverWins()
   158 //
   159 // Constructor
   160 //
   161 	{
   162 
   163 	TPckg<TScreenInfoV01> sI(iScreenInfo);
   164 	UserSvr::ScreenInfo(sI);
   165 	iPalette=(rgbValues *)User::Alloc(256*sizeof(rgbValues));
   166 	}
   167 
   168 EXPORT_C CScreenDriver *CScreenDriver::New()
   169 //
   170 // Return the actual screen driver.
   171 //
   172 	{
   173 
   174 	CScreenDriverWins *pS=new CScreenDriverWins;
   175     if (!pS)
   176     	return(NULL);
   177 	if (!pS->iScreenInfo.iWindowHandleValid)
   178 		{
   179 		delete pS;
   180     	return(NULL);
   181 		}
   182     pS->iTextScreenSize=pS->iScreenInfo.iScreenSize;
   183 	pS->iTextScreenSize.iWidth/=FONTWIDTH; // Convert from GDI units to character positions
   184 	pS->iTextScreenSize.iHeight/=FONTHEIGHT;
   185     pS->iScreenBuffer=new TText[pS->iTextScreenSize.iWidth*pS->iTextScreenSize.iHeight];
   186     if (!pS->iScreenBuffer)
   187 		{
   188 		delete pS;
   189         return(NULL);
   190 		}
   191 	
   192 	__LOCK_HOST;
   193 	HWND win=(HWND)pS->iScreenInfo.iWindowHandle;
   194 	pS->iDc=GetDC(win);
   195 	DWORD fontCharacterSet;
   196 	LANGID language;
   197 	fontCharacterSet=ANSI_CHARSET;
   198 	language=(LANGID)PRIMARYLANGID(GetSystemDefaultLangID());
   199 	if (language==LANG_JAPANESE) fontCharacterSet=SHIFTJIS_CHARSET;
   200 	pS->iFont=CreateFontA(FONTHEIGHT+1,      // logical font height
   201 						FONTWIDTH+1,        // logical average character width
   202 						0,                  // angle of escapement
   203 						0,                  // base-line orientation angle
   204 						FW_DONTCARE,        // font weight
   205 						0,                  // italic attribute
   206 						0,                  // underline attribute
   207 						0,                  // strikeout attribute
   208 				        fontCharacterSet,	// character set identifier
   209 						OUT_RASTER_PRECIS,  // output precision
   210 						CLIP_CHARACTER_PRECIS, // clipping precision
   211 						DEFAULT_QUALITY,    // output quality
   212 						FIXED_PITCH,        // pitch and family
   213 						"Terminal"          // typeface name string
   214 				        );
   215 	if (!pS->iFont)
   216 		{
   217 		delete pS->iScreenBuffer;
   218 		delete pS;
   219 		return(NULL);
   220 		}
   221 
   222 	// On some Windows9x PCs, the font we assume under NT isn't always present,
   223 	// but it's important we get a font with height 12.  Therefore increase the
   224 	// height setting and try again.  This seems always to do the trick.
   225 	TEXTMETRIC textMetrics;
   226 	HFONT oldFont=REINTERPRET_CAST(HFONT,SelectObject(pS->iDc,pS->iFont));
   227 	TBool tryNewFont=FALSE;
   228 	if (GetTextMetrics(pS->iDc, &textMetrics) && (textMetrics.tmHeight<12))
   229 		tryNewFont=TRUE;
   230 	SelectObject(pS->iDc, oldFont);
   231 	if (tryNewFont)
   232 		{
   233 		HFONT newFont=CreateFontA(FONTHEIGHT+2,
   234 							FONTWIDTH+1,
   235 							0,
   236 							0,
   237 							FW_DONTCARE,
   238 							0,
   239 							0,
   240 							0,
   241 							fontCharacterSet,
   242 							OUT_RASTER_PRECIS,
   243 							CLIP_CHARACTER_PRECIS,
   244 							DEFAULT_QUALITY,
   245 							FIXED_PITCH,
   246 							"Terminal"
   247 							);
   248 		if (newFont)
   249 			pS->iFont=newFont;
   250 		}
   251 
   252 	return(pS);
   253 	}
   254 
   255 void CScreenDriverWins::Init(TSize &aScreenSize,TSize &aFontSize)
   256 //
   257 // Report screen information
   258 //
   259 	{
   260 
   261 	aFontSize=TSize(FONTWIDTH,FONTHEIGHT);
   262 	aScreenSize=iTextScreenSize;
   263 	}
   264 
   265 TInt CScreenDriverWins::SetMode(TVideoMode aMode)
   266 //
   267 // Set the screen mode
   268 //
   269 	{
   270 
   271 //  Reset the palette
   272 
   273     if (aMode==EColor256)
   274         {
   275         TInt x, y, z, t;
   276 
   277     	for(t=0;t<16;t++)
   278     		{
   279     		iPalette[t].iRed=(TUint8)(t*8);
   280             iPalette[t].iGreen=(TUint8)(t*8);
   281             iPalette[t].iBlue=(TUint8)(t*8);
   282     		}
   283     	for(t=16;t<32;t++)
   284     		{
   285     		iPalette[t].iRed=(TUint8)(t*8+7);
   286             iPalette[t].iGreen=(TUint8)(t*8+7);
   287             iPalette[t].iBlue=(TUint8)(t*8+7);
   288     		}
   289     	for(x=0;x<2;x++)
   290     		for(y=0;y<2;y++)
   291     			for(z=0;z<2;z++)
   292     				{
   293     				iPalette[t].iRed=(TUint8)(x*255);
   294     				iPalette[t].iGreen=(TUint8)(y*255);
   295     				iPalette[t].iBlue=(TUint8)(z*255);
   296                     t++;
   297     				}
   298     	for(x=0;x<6;x++)
   299     		for(y=0;y<6;y++)
   300     			for(z=0;z<6;z++)
   301     				{
   302     				iPalette[t].iRed=(TUint8)(x*51);
   303     				iPalette[t].iGreen=(TUint8)(y*51);
   304     				iPalette[t].iBlue=(TUint8)(z*51);
   305                     t++;
   306     				}
   307         iMode=aMode;
   308         return(KErrNone);
   309         }
   310     if (aMode==EMono)
   311         {
   312         iPalette[0].iRed=KMonoRed0;
   313         iPalette[0].iGreen=KMonoGreen0;
   314         iPalette[0].iBlue=KMonoBlue0;
   315         iPalette[1].iRed=KMonoRed1;
   316         iPalette[1].iGreen=KMonoGreen1;
   317         iPalette[1].iBlue=KMonoBlue1;
   318         iMode=aMode;
   319         return(KErrNone);
   320         }
   321 	return(KErrNotSupported);
   322     }
   323 
   324 void CScreenDriverWins::Blit(const TText *aBuffer, TInt aLength, const TPoint &aPosition)
   325 //
   326 // Write contiguous block of characters to some segment of a line on the display
   327 //
   328 	{
   329 
   330 	if (iDc)
   331 	    {
   332 
   333         // Create a font of the appropriate metrics.  The character
   334         // set selection depends on the context.  The text console
   335         // was originally designed with the code page 850 line drawing
   336         // characters, so in the 8-bit version we continue to select
   337         // this, until we are in a position to supply a specific font
   338         // with the SDK.  In the 16-bit version, we can use an ANSI
   339         // font and the proper line drawing characters defined in Unicode.
   340         // For a Japanese environment, an attempt is made to select a
   341         // font that supports the shift-JIS character set.
   342 
   343 		__LOCK_HOST;
   344 		HFONT oldFont=REINTERPRET_CAST(HFONT,SelectObject(iDc,iFont));
   345 		if (oldFont)
   346 			{
   347 			TPtrC buf(aBuffer,aLength);
   348 			TBuf<0x100> b;
   349 			b.Copy(buf);
   350 			TText* code =(TText*)b.Ptr();
   351             Mem::Copy(iScreenBuffer+((aPosition.iY*iTextScreenSize.iWidth)+aPosition.iX),code,aLength*2);
   352 			TPoint ap=GraphicsPosition(aPosition);
   353 			for (TInt i=0;i<aLength;++i)
   354 				{
   355 				TInt fontWidth = IsHankaku(*code) ? FONTWIDTH : FONTWIDTH*2;
   356 				RECT rect;
   357 				SetRect(&rect, ap.iX, ap.iY, ap.iX + fontWidth, ap.iY + FONTHEIGHT);
   358 				// The following function is better than TextOutW because it will fill in the gaps
   359 				// if we get a font smaller than the appropriate size.
   360 				ExtTextOutW(iDc, ap.iX, ap.iY, ETO_OPAQUE, &rect, (const unsigned short *)code, 1, NULL);
   361 				ap.iX+=fontWidth;
   362 				code++;
   363 				}
   364 			SelectObject(iDc,oldFont);
   365 			}
   366 		GdiFlush();
   367 		}
   368 	}
   369 
   370 TBool CScreenDriverWins::ScrollUp(const TRect& aRect)
   371 //
   372 // Scroll a rectangle of the screen up one line, the bottom line is not updated, return ETrue on sucess
   373 //
   374 	{
   375 
   376 	ScreenBufferScrollUp(aRect);
   377 	// Create MSVC RECT from E32 TRect
   378 	__LOCK_HOST;
   379 	RECT rect;
   380 	rect.left=(aRect.iTl.iX)*FONTWIDTH;
   381 	rect.top=(aRect.iTl.iY+1)*FONTHEIGHT;
   382 	rect.right=(aRect.iBr.iX)*FONTWIDTH;
   383 	rect.bottom=(aRect.iBr.iY)*FONTHEIGHT;
   384 	RECT updateRect;
   385 	ScrollWindowEx((HWND)iScreenInfo.iWindowHandle,0,-FONTHEIGHT,&rect,NULL,NULL,&updateRect,0);
   386 	GdiFlush();
   387 	if (updateRect.bottom==0 || (rect.bottom==updateRect.bottom && updateRect.bottom==updateRect.top+FONTHEIGHT))
   388 		return ETrue;
   389 	return EFalse;
   390 	}
   391 
   392 void CScreenDriverWins::Clear(const TRect& aRect)
   393 //
   394 // Clear a rectangle of the screen
   395 //
   396 	{
   397 
   398 	ScreenBufferClear(aRect);
   399 	// Create MSVC RECT from E32 TRect
   400 	__LOCK_HOST;
   401 	RECT rect;
   402 	rect.left=(aRect.iTl.iX)*FONTWIDTH;
   403 	rect.top=(aRect.iTl.iY)*FONTHEIGHT;
   404 	rect.right=(aRect.iBr.iX)*FONTWIDTH;
   405 	rect.bottom=(aRect.iBr.iY)*FONTHEIGHT;
   406 	FillRect(GetDC((HWND)iScreenInfo.iWindowHandle),&rect,NULL); 
   407 	GdiFlush();
   408 	}
   409 
   410 void CScreenDriverWins::SetPaletteEntry(TColorIndex anIndex,TUint8 aRed,TUint8 aGreen,TUint8 aBlue)
   411 	{
   412 
   413 	if(iMode==EColor256)
   414 		{
   415 		iPalette[anIndex].iRed=aRed;iPalette[anIndex].iGreen=aGreen;iPalette[anIndex].iBlue=aBlue;
   416 		}
   417 	}
   418 
   419 void CScreenDriverWins::GetPaletteEntry(TColorIndex anIndex,TUint8 &aRed,TUint8 &aGreen,TUint8 &aBlue)
   420 	{
   421 	
   422 	aRed=iPalette[anIndex].iRed;aGreen=iPalette[anIndex].iGreen;aBlue=iPalette[anIndex].iBlue;
   423 	}
   424 
   425 void CScreenDriverWins::SetForegroundColor(TColorIndex anIndex)
   426 	{
   427 
   428 	__LOCK_HOST;
   429     TInt index=anIndex;
   430 	index=Min(index,(1<<iMode)-1);
   431 	SetTextColor(iDc,RGB(iPalette[index].iRed,iPalette[index].iGreen,iPalette[index].iBlue));
   432 	GdiFlush();
   433 	}
   434 
   435 void CScreenDriverWins::SetBackgroundColor(TColorIndex anIndex)
   436 	{
   437 	
   438 	__LOCK_HOST;
   439     TInt index=anIndex;
   440 	index=Min(index,(1<<iMode)-1);
   441 	SetBkColor(iDc,RGB(iPalette[index].iRed,iPalette[index].iGreen,iPalette[index].iBlue));
   442 	GdiFlush();
   443 	}
   444 
   445 void CScreenDriverWins::GetAttributeColors(TColorIndex* anArray)
   446 //
   447 //
   448 //
   449 	{
   450 	if(iMode==EMono)
   451         Mem::Copy(anArray,KMonoAttributes,sizeof(KMonoAttributes));
   452 	else if(iMode==EColor256)
   453         Mem::Copy(anArray,KColor256Attributes,sizeof(KColor256Attributes));
   454 	}
   455 
   456 void CScreenDriverWins::SetPixel(const TPoint& /*aPoint*/,TUint8 /*aColour*/)
   457 	{
   458 	}
   459 
   460 TInt CScreenDriverWins::GetPixel(const TPoint& /*aPoint*/)
   461 	{
   462 	return 0;
   463 	}
   464 
   465 void CScreenDriverWins::SetWord(const TPoint& /*aPoint*/,TInt /*aWord*/)
   466 	{
   467 	}
   468 
   469 TInt CScreenDriverWins::GetWord(const TPoint& /*aPoint*/)
   470 	{
   471 	return 0;
   472 	}
   473 
   474 void CScreenDriverWins::SetLine(const TPoint& /*aPoint*/,const TPixelLine& /*aPixelLine*/)
   475 	{
   476 	}
   477 
   478 void CScreenDriverWins::GetLine(const TPoint& /*aPoint*/,TPixelLine& /*aPixelLine*/)
   479 	{
   480 	}
   481