1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/kernelhwsrv/kernel/eka/drivers/edisp/emul/win32/wd_wins.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,481 @@
1.4 +// Copyright (c) 1995-2009 Nokia Corporation and/or its subsidiary(-ies).
1.5 +// All rights reserved.
1.6 +// This component and the accompanying materials are made available
1.7 +// under the terms of the License "Eclipse Public License v1.0"
1.8 +// which accompanies this distribution, and is available
1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
1.10 +//
1.11 +// Initial Contributors:
1.12 +// Nokia Corporation - initial contribution.
1.13 +//
1.14 +// Contributors:
1.15 +//
1.16 +// Description:
1.17 +// e32\drivers\edisp\emul\win32\wd_wins.cpp
1.18 +//
1.19 +//
1.20 +
1.21 +#include <e32cmn.h>
1.22 +#include <e32cmn_private.h>
1.23 +#include <emulator.h>
1.24 +#define WIN32_LEAN_AND_MEAN
1.25 +#pragma warning( disable : 4201 ) // nonstandard extension used : nameless struct/union
1.26 +#include <windows.h>
1.27 +#pragma warning( default : 4201 ) // nonstandard extension used : nameless struct/union
1.28 +#include "ws_std.h"
1.29 +
1.30 +// Driver for WINS platform using windows stock font
1.31 +
1.32 +#define FONTWIDTH 8
1.33 +#define FONTHEIGHT 12
1.34 +
1.35 +struct rgbValues{
1.36 + TUint8 iRed;
1.37 + TUint8 iGreen;
1.38 + TUint8 iBlue;
1.39 + };
1.40 +
1.41 +const TUint8 KMonoRed0=50;
1.42 +const TUint8 KMonoGreen0=100;
1.43 +const TUint8 KMonoBlue0=200;
1.44 +const TUint8 KMonoRed1=250;
1.45 +const TUint8 KMonoGreen1=250;
1.46 +const TUint8 KMonoBlue1=20;
1.47 +
1.48 +const TColorIndex KMonoAttributes[8]=
1.49 + {
1.50 + 1, // Normal foreground
1.51 + 0, // Normal background
1.52 + 1, // Bold foreground
1.53 + 0, // Bold background
1.54 + 0, // Inverse foreground
1.55 + 1, // Inverse background
1.56 + 0, // Highlight foreground
1.57 + 1 // Highlight background
1.58 + };
1.59 +
1.60 +const TColorIndex KColor256Attributes[8]=
1.61 + {
1.62 + 38, // Normal foreground
1.63 + 33, // Normal background
1.64 + 36, // Bold foreground
1.65 + 38, // Bold background
1.66 + 33, // Inverse foreground
1.67 + 38, // Inverse background
1.68 + 38, // Highlight foreground
1.69 + 36 // Highlight background
1.70 + };
1.71 +
1.72 +class CScreenDriverWins : public CScreenDriver
1.73 + {
1.74 + friend class CScreenDriver;
1.75 +public:
1.76 + CScreenDriverWins();
1.77 + virtual void Init(TSize &aScreenSize,TSize &aFontSize);
1.78 + virtual void Blit(const TText *aBuffer,TInt aLength,const TPoint &aPosition);
1.79 + virtual TBool ScrollUp(const TRect& aRect);
1.80 + virtual void Clear(const TRect& aRect);
1.81 +
1.82 + virtual void SetPixel(const TPoint& aPoint,TUint8 aColour);
1.83 + virtual TInt GetPixel(const TPoint& aPoint);
1.84 + virtual void SetWord(const TPoint& aPoint,TInt aWord);
1.85 + virtual TInt GetWord(const TPoint& aPoint);
1.86 + virtual void SetLine(const TPoint& aPoint,const TPixelLine& aPixelLine);
1.87 + virtual void GetLine(const TPoint& aPoint,TPixelLine& aPixelLine);
1.88 + virtual void SetPaletteEntry(TColorIndex anIndex,TUint8 aRed,TUint8 aGreen,TUint8 aBlue);
1.89 + virtual void GetPaletteEntry(TColorIndex anIndex,TUint8 &aRed,TUint8 &aGreen,TUint8 &aBlue);
1.90 + virtual void SetForegroundColor(TColorIndex anIndex);
1.91 + virtual void SetBackgroundColor(TColorIndex anIndex);
1.92 + virtual void GetAttributeColors(TColorIndex* anArray);
1.93 +
1.94 + virtual TInt SetMode(TVideoMode aMode);
1.95 +
1.96 + static TBool IsHankaku(const TText aCode);
1.97 + virtual TPoint GraphicsPosition(const TPoint& aPosition);
1.98 + virtual void ScreenBufferScrollUp(const TRect& aRect);
1.99 + virtual void ScreenBufferClear(const TRect& aRect);
1.100 +private:
1.101 + TText* iScreenBuffer;
1.102 +
1.103 +private:
1.104 + HFONT iFont;
1.105 + HDC iDc;
1.106 + TSize iTextScreenSize;
1.107 + TScreenInfoV01 iScreenInfo;
1.108 + TVideoMode iMode;
1.109 + rgbValues* iPalette;
1.110 + };
1.111 +
1.112 +
1.113 +TPoint CScreenDriverWins::GraphicsPosition(const TPoint& aPosition)
1.114 + {
1.115 + TPoint pos(0,aPosition.iY*FONTHEIGHT);
1.116 + TText* pS=iScreenBuffer+(iTextScreenSize.iWidth*aPosition.iY);
1.117 + TText* pE=pS+aPosition.iX;
1.118 + for (TText* pT=pS;pT<pE;++pT)
1.119 + pos.iX+=IsHankaku(*pT) ? FONTWIDTH : FONTWIDTH*2;
1.120 + return(pos);
1.121 + }
1.122 +
1.123 +TBool CScreenDriverWins::IsHankaku(const TText aCode)
1.124 + {
1.125 + if (aCode >= 0xff61 && aCode <= 0xff9f)
1.126 + return ETrue; // HANKAKU KATAKANA code
1.127 + if (aCode >= 0x2550 && aCode <= 0x259f)
1.128 + return ETrue; // HANKAKU Graphics code
1.129 + if (aCode < 0x100)
1.130 + return ETrue; // Alphanumeric codes means HANKAKU
1.131 + return EFalse;
1.132 + }
1.133 +
1.134 +void CScreenDriverWins::ScreenBufferScrollUp(const TRect& aRect)
1.135 + {
1.136 + TText* src=&iScreenBuffer[(aRect.iTl.iY+1)*iTextScreenSize.iWidth+aRect.iTl.iX];
1.137 + TText* dest=&iScreenBuffer[aRect.iTl.iY*iTextScreenSize.iWidth+aRect.iTl.iX];
1.138 + for (TInt j=0;j<aRect.iBr.iY-aRect.iTl.iY;++j)
1.139 + {
1.140 + TInt r=j*iTextScreenSize.iWidth;
1.141 + for (TInt i=0;i<aRect.iBr.iX-aRect.iTl.iX+1;++i)
1.142 + {
1.143 + TInt p = r+i;
1.144 + dest[p] = src[p];
1.145 + }
1.146 + }
1.147 + }
1.148 +
1.149 +void CScreenDriverWins::ScreenBufferClear(const TRect& aRect)
1.150 + {
1.151 + TText* dest=&iScreenBuffer[aRect.iTl.iY*iTextScreenSize.iWidth+aRect.iTl.iX];
1.152 + for (TInt j=0;j<aRect.iBr.iY-aRect.iTl.iY+1;++j)
1.153 + {
1.154 + TInt r=j*iTextScreenSize.iWidth;
1.155 + for (TInt i=0;i<aRect.iBr.iX-aRect.iTl.iX+1;++i)
1.156 + dest[r+i] = 0x0020;
1.157 + }
1.158 + }
1.159 +
1.160 +CScreenDriverWins::CScreenDriverWins()
1.161 +//
1.162 +// Constructor
1.163 +//
1.164 + {
1.165 +
1.166 + TPckg<TScreenInfoV01> sI(iScreenInfo);
1.167 + UserSvr::ScreenInfo(sI);
1.168 + iPalette=(rgbValues *)User::Alloc(256*sizeof(rgbValues));
1.169 + }
1.170 +
1.171 +EXPORT_C CScreenDriver *CScreenDriver::New()
1.172 +//
1.173 +// Return the actual screen driver.
1.174 +//
1.175 + {
1.176 +
1.177 + CScreenDriverWins *pS=new CScreenDriverWins;
1.178 + if (!pS)
1.179 + return(NULL);
1.180 + if (!pS->iScreenInfo.iWindowHandleValid)
1.181 + {
1.182 + delete pS;
1.183 + return(NULL);
1.184 + }
1.185 + pS->iTextScreenSize=pS->iScreenInfo.iScreenSize;
1.186 + pS->iTextScreenSize.iWidth/=FONTWIDTH; // Convert from GDI units to character positions
1.187 + pS->iTextScreenSize.iHeight/=FONTHEIGHT;
1.188 + pS->iScreenBuffer=new TText[pS->iTextScreenSize.iWidth*pS->iTextScreenSize.iHeight];
1.189 + if (!pS->iScreenBuffer)
1.190 + {
1.191 + delete pS;
1.192 + return(NULL);
1.193 + }
1.194 +
1.195 + __LOCK_HOST;
1.196 + HWND win=(HWND)pS->iScreenInfo.iWindowHandle;
1.197 + pS->iDc=GetDC(win);
1.198 + DWORD fontCharacterSet;
1.199 + LANGID language;
1.200 + fontCharacterSet=ANSI_CHARSET;
1.201 + language=(LANGID)PRIMARYLANGID(GetSystemDefaultLangID());
1.202 + if (language==LANG_JAPANESE) fontCharacterSet=SHIFTJIS_CHARSET;
1.203 + pS->iFont=CreateFontA(FONTHEIGHT+1, // logical font height
1.204 + FONTWIDTH+1, // logical average character width
1.205 + 0, // angle of escapement
1.206 + 0, // base-line orientation angle
1.207 + FW_DONTCARE, // font weight
1.208 + 0, // italic attribute
1.209 + 0, // underline attribute
1.210 + 0, // strikeout attribute
1.211 + fontCharacterSet, // character set identifier
1.212 + OUT_RASTER_PRECIS, // output precision
1.213 + CLIP_CHARACTER_PRECIS, // clipping precision
1.214 + DEFAULT_QUALITY, // output quality
1.215 + FIXED_PITCH, // pitch and family
1.216 + "Terminal" // typeface name string
1.217 + );
1.218 + if (!pS->iFont)
1.219 + {
1.220 + delete pS->iScreenBuffer;
1.221 + delete pS;
1.222 + return(NULL);
1.223 + }
1.224 +
1.225 + // On some Windows9x PCs, the font we assume under NT isn't always present,
1.226 + // but it's important we get a font with height 12. Therefore increase the
1.227 + // height setting and try again. This seems always to do the trick.
1.228 + TEXTMETRIC textMetrics;
1.229 + HFONT oldFont=REINTERPRET_CAST(HFONT,SelectObject(pS->iDc,pS->iFont));
1.230 + TBool tryNewFont=FALSE;
1.231 + if (GetTextMetrics(pS->iDc, &textMetrics) && (textMetrics.tmHeight<12))
1.232 + tryNewFont=TRUE;
1.233 + SelectObject(pS->iDc, oldFont);
1.234 + if (tryNewFont)
1.235 + {
1.236 + HFONT newFont=CreateFontA(FONTHEIGHT+2,
1.237 + FONTWIDTH+1,
1.238 + 0,
1.239 + 0,
1.240 + FW_DONTCARE,
1.241 + 0,
1.242 + 0,
1.243 + 0,
1.244 + fontCharacterSet,
1.245 + OUT_RASTER_PRECIS,
1.246 + CLIP_CHARACTER_PRECIS,
1.247 + DEFAULT_QUALITY,
1.248 + FIXED_PITCH,
1.249 + "Terminal"
1.250 + );
1.251 + if (newFont)
1.252 + pS->iFont=newFont;
1.253 + }
1.254 +
1.255 + return(pS);
1.256 + }
1.257 +
1.258 +void CScreenDriverWins::Init(TSize &aScreenSize,TSize &aFontSize)
1.259 +//
1.260 +// Report screen information
1.261 +//
1.262 + {
1.263 +
1.264 + aFontSize=TSize(FONTWIDTH,FONTHEIGHT);
1.265 + aScreenSize=iTextScreenSize;
1.266 + }
1.267 +
1.268 +TInt CScreenDriverWins::SetMode(TVideoMode aMode)
1.269 +//
1.270 +// Set the screen mode
1.271 +//
1.272 + {
1.273 +
1.274 +// Reset the palette
1.275 +
1.276 + if (aMode==EColor256)
1.277 + {
1.278 + TInt x, y, z, t;
1.279 +
1.280 + for(t=0;t<16;t++)
1.281 + {
1.282 + iPalette[t].iRed=(TUint8)(t*8);
1.283 + iPalette[t].iGreen=(TUint8)(t*8);
1.284 + iPalette[t].iBlue=(TUint8)(t*8);
1.285 + }
1.286 + for(t=16;t<32;t++)
1.287 + {
1.288 + iPalette[t].iRed=(TUint8)(t*8+7);
1.289 + iPalette[t].iGreen=(TUint8)(t*8+7);
1.290 + iPalette[t].iBlue=(TUint8)(t*8+7);
1.291 + }
1.292 + for(x=0;x<2;x++)
1.293 + for(y=0;y<2;y++)
1.294 + for(z=0;z<2;z++)
1.295 + {
1.296 + iPalette[t].iRed=(TUint8)(x*255);
1.297 + iPalette[t].iGreen=(TUint8)(y*255);
1.298 + iPalette[t].iBlue=(TUint8)(z*255);
1.299 + t++;
1.300 + }
1.301 + for(x=0;x<6;x++)
1.302 + for(y=0;y<6;y++)
1.303 + for(z=0;z<6;z++)
1.304 + {
1.305 + iPalette[t].iRed=(TUint8)(x*51);
1.306 + iPalette[t].iGreen=(TUint8)(y*51);
1.307 + iPalette[t].iBlue=(TUint8)(z*51);
1.308 + t++;
1.309 + }
1.310 + iMode=aMode;
1.311 + return(KErrNone);
1.312 + }
1.313 + if (aMode==EMono)
1.314 + {
1.315 + iPalette[0].iRed=KMonoRed0;
1.316 + iPalette[0].iGreen=KMonoGreen0;
1.317 + iPalette[0].iBlue=KMonoBlue0;
1.318 + iPalette[1].iRed=KMonoRed1;
1.319 + iPalette[1].iGreen=KMonoGreen1;
1.320 + iPalette[1].iBlue=KMonoBlue1;
1.321 + iMode=aMode;
1.322 + return(KErrNone);
1.323 + }
1.324 + return(KErrNotSupported);
1.325 + }
1.326 +
1.327 +void CScreenDriverWins::Blit(const TText *aBuffer, TInt aLength, const TPoint &aPosition)
1.328 +//
1.329 +// Write contiguous block of characters to some segment of a line on the display
1.330 +//
1.331 + {
1.332 +
1.333 + if (iDc)
1.334 + {
1.335 +
1.336 + // Create a font of the appropriate metrics. The character
1.337 + // set selection depends on the context. The text console
1.338 + // was originally designed with the code page 850 line drawing
1.339 + // characters, so in the 8-bit version we continue to select
1.340 + // this, until we are in a position to supply a specific font
1.341 + // with the SDK. In the 16-bit version, we can use an ANSI
1.342 + // font and the proper line drawing characters defined in Unicode.
1.343 + // For a Japanese environment, an attempt is made to select a
1.344 + // font that supports the shift-JIS character set.
1.345 +
1.346 + __LOCK_HOST;
1.347 + HFONT oldFont=REINTERPRET_CAST(HFONT,SelectObject(iDc,iFont));
1.348 + if (oldFont)
1.349 + {
1.350 + TPtrC buf(aBuffer,aLength);
1.351 + TBuf<0x100> b;
1.352 + b.Copy(buf);
1.353 + TText* code =(TText*)b.Ptr();
1.354 + Mem::Copy(iScreenBuffer+((aPosition.iY*iTextScreenSize.iWidth)+aPosition.iX),code,aLength*2);
1.355 + TPoint ap=GraphicsPosition(aPosition);
1.356 + for (TInt i=0;i<aLength;++i)
1.357 + {
1.358 + TInt fontWidth = IsHankaku(*code) ? FONTWIDTH : FONTWIDTH*2;
1.359 + RECT rect;
1.360 + SetRect(&rect, ap.iX, ap.iY, ap.iX + fontWidth, ap.iY + FONTHEIGHT);
1.361 + // The following function is better than TextOutW because it will fill in the gaps
1.362 + // if we get a font smaller than the appropriate size.
1.363 + ExtTextOutW(iDc, ap.iX, ap.iY, ETO_OPAQUE, &rect, (const unsigned short *)code, 1, NULL);
1.364 + ap.iX+=fontWidth;
1.365 + code++;
1.366 + }
1.367 + SelectObject(iDc,oldFont);
1.368 + }
1.369 + GdiFlush();
1.370 + }
1.371 + }
1.372 +
1.373 +TBool CScreenDriverWins::ScrollUp(const TRect& aRect)
1.374 +//
1.375 +// Scroll a rectangle of the screen up one line, the bottom line is not updated, return ETrue on sucess
1.376 +//
1.377 + {
1.378 +
1.379 + ScreenBufferScrollUp(aRect);
1.380 + // Create MSVC RECT from E32 TRect
1.381 + __LOCK_HOST;
1.382 + RECT rect;
1.383 + rect.left=(aRect.iTl.iX)*FONTWIDTH;
1.384 + rect.top=(aRect.iTl.iY+1)*FONTHEIGHT;
1.385 + rect.right=(aRect.iBr.iX)*FONTWIDTH;
1.386 + rect.bottom=(aRect.iBr.iY)*FONTHEIGHT;
1.387 + RECT updateRect;
1.388 + ScrollWindowEx((HWND)iScreenInfo.iWindowHandle,0,-FONTHEIGHT,&rect,NULL,NULL,&updateRect,0);
1.389 + GdiFlush();
1.390 + if (updateRect.bottom==0 || (rect.bottom==updateRect.bottom && updateRect.bottom==updateRect.top+FONTHEIGHT))
1.391 + return ETrue;
1.392 + return EFalse;
1.393 + }
1.394 +
1.395 +void CScreenDriverWins::Clear(const TRect& aRect)
1.396 +//
1.397 +// Clear a rectangle of the screen
1.398 +//
1.399 + {
1.400 +
1.401 + ScreenBufferClear(aRect);
1.402 + // Create MSVC RECT from E32 TRect
1.403 + __LOCK_HOST;
1.404 + RECT rect;
1.405 + rect.left=(aRect.iTl.iX)*FONTWIDTH;
1.406 + rect.top=(aRect.iTl.iY)*FONTHEIGHT;
1.407 + rect.right=(aRect.iBr.iX)*FONTWIDTH;
1.408 + rect.bottom=(aRect.iBr.iY)*FONTHEIGHT;
1.409 + FillRect(GetDC((HWND)iScreenInfo.iWindowHandle),&rect,NULL);
1.410 + GdiFlush();
1.411 + }
1.412 +
1.413 +void CScreenDriverWins::SetPaletteEntry(TColorIndex anIndex,TUint8 aRed,TUint8 aGreen,TUint8 aBlue)
1.414 + {
1.415 +
1.416 + if(iMode==EColor256)
1.417 + {
1.418 + iPalette[anIndex].iRed=aRed;iPalette[anIndex].iGreen=aGreen;iPalette[anIndex].iBlue=aBlue;
1.419 + }
1.420 + }
1.421 +
1.422 +void CScreenDriverWins::GetPaletteEntry(TColorIndex anIndex,TUint8 &aRed,TUint8 &aGreen,TUint8 &aBlue)
1.423 + {
1.424 +
1.425 + aRed=iPalette[anIndex].iRed;aGreen=iPalette[anIndex].iGreen;aBlue=iPalette[anIndex].iBlue;
1.426 + }
1.427 +
1.428 +void CScreenDriverWins::SetForegroundColor(TColorIndex anIndex)
1.429 + {
1.430 +
1.431 + __LOCK_HOST;
1.432 + TInt index=anIndex;
1.433 + index=Min(index,(1<<iMode)-1);
1.434 + SetTextColor(iDc,RGB(iPalette[index].iRed,iPalette[index].iGreen,iPalette[index].iBlue));
1.435 + GdiFlush();
1.436 + }
1.437 +
1.438 +void CScreenDriverWins::SetBackgroundColor(TColorIndex anIndex)
1.439 + {
1.440 +
1.441 + __LOCK_HOST;
1.442 + TInt index=anIndex;
1.443 + index=Min(index,(1<<iMode)-1);
1.444 + SetBkColor(iDc,RGB(iPalette[index].iRed,iPalette[index].iGreen,iPalette[index].iBlue));
1.445 + GdiFlush();
1.446 + }
1.447 +
1.448 +void CScreenDriverWins::GetAttributeColors(TColorIndex* anArray)
1.449 +//
1.450 +//
1.451 +//
1.452 + {
1.453 + if(iMode==EMono)
1.454 + Mem::Copy(anArray,KMonoAttributes,sizeof(KMonoAttributes));
1.455 + else if(iMode==EColor256)
1.456 + Mem::Copy(anArray,KColor256Attributes,sizeof(KColor256Attributes));
1.457 + }
1.458 +
1.459 +void CScreenDriverWins::SetPixel(const TPoint& /*aPoint*/,TUint8 /*aColour*/)
1.460 + {
1.461 + }
1.462 +
1.463 +TInt CScreenDriverWins::GetPixel(const TPoint& /*aPoint*/)
1.464 + {
1.465 + return 0;
1.466 + }
1.467 +
1.468 +void CScreenDriverWins::SetWord(const TPoint& /*aPoint*/,TInt /*aWord*/)
1.469 + {
1.470 + }
1.471 +
1.472 +TInt CScreenDriverWins::GetWord(const TPoint& /*aPoint*/)
1.473 + {
1.474 + return 0;
1.475 + }
1.476 +
1.477 +void CScreenDriverWins::SetLine(const TPoint& /*aPoint*/,const TPixelLine& /*aPixelLine*/)
1.478 + {
1.479 + }
1.480 +
1.481 +void CScreenDriverWins::GetLine(const TPoint& /*aPoint*/,TPixelLine& /*aPixelLine*/)
1.482 + {
1.483 + }
1.484 +