First public contribution.
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 "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".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
14 // wins\specific\gui.cpp
22 #include <kernel/kern_priv.h>
23 #include <kernel/kpower.h>
27 #include "display_chan.h"
28 #include "pixelformats.h"
29 #include "multitouch.h"
33 //Define these so that emulator generates varying values for gce stride and offset.
34 //By default in emulator, stride is exactly right for display resolution and offset is zero
35 //Setting these will identify code which incorrectly calculates these factors instead of requesting them
36 //Note that multiples of 4 bytes are preferred for various reasons.
37 //[3/5/07 The Secure presentation burffer ignores stride extra because it uses a windows bitmap header to render.]
38 // #define TEST_GCE_VARIABLE_STRIDE_EXTRA 16 //This constant is added to each mode's scanline length in bytes. It may cause a break if enabled because the iDisplayBufferOffset is not being set
39 // #define TEST_GCE_VARIABLE_START_EXTRA 16 //A multiple of this is added to each mode's start address in bytes
40 // #define ASSYMETRIC_SQUARE_STRIDE //If this is defined and the width==height the the stride will not be the same!
44 KMaskModeNum=0x0FFFFFFF,
45 KMaskModeFlag8=0x80000000,
46 KMaskModeFlag4=0x40000000,
47 KMaskModeFlag2=0x20000000,
48 KMaskModeFlag1=0x10000000,
50 KModeFlagFlipped=KMaskModeFlag8,
55 KMaskScreenNum=0x0FFF,
56 KMaskScreenFlag8=0x8000,
57 KMaskScreenFlag4=0x4000,
58 KMaskScreenFlag2=0x2000,
59 KMaskScreenFlag1=0x1000,
61 KScreenFlagSecure=KMaskScreenFlag8,
64 const TInt KMaxDisplayColors=16777216;
65 const TInt KMaxDisplayContrast=1;
67 static TEmulatorFlip* CurrentFlipState=NULL;
68 static TInt CurrentConfiguration = 0;
69 static TInt SavedFlipMessage = 0;
71 DWinsUi *systemIni=NULL;
72 DMasterIni* masterIni;
74 DMultiTouch* TheMultiTouch;
75 static HWND TheControlWin;
76 static HWND* TheChildWin=NULL;
77 static HWND* TheWin=NULL;
78 static HWND hwndStatus; // To display the X,Y,Z information of each mouse
79 static TInt VirtualKeyPressed = EStdKeyNull;
80 static HBITMAP* TheScreenBitmap=NULL;
82 static TBool WsSwitchOnScreen;
84 const char * DefaultWindowTitle = "Symbian OS Emulator";
89 const char * VersionText = " - wins udeb";
91 const char * VersionText = " - wins urel";
98 const char * VersionText = " - winscw udeb";
100 const char * VersionText = " - winscw urel";
104 //not winscw or wins!
106 const char * VersionText = " - unknown udeb";
108 const char * VersionText = " - unknown urel");
117 void UpdateModifiers();
118 TInt DisplayHalFunction(TAny*, TInt aFunction, TAny* a1, TAny* a2);
119 LOCAL_C TBool PaintWindowFromBuffer(HWND hWnd);
121 GLDEF_C const char* skipws(const char* aPtr)
123 while (isspace(*aPtr))
128 GLDEF_C const char* skiptok(const char* aPtr)
130 while (isalnum(*aPtr))
135 GLDEF_C TInt CompareI(const TDesC8& aLhs, const TDesC8& aRhs)
137 // Case insensitive comparison of descriptors
138 // (TDesC::CompareF not available to kernel side code)
141 TInt ll = aLhs.Length();
142 TInt rl = aRhs.Length();
143 TInt len = Min(ll, rl);
144 TInt k = _strnicmp((const char*)aLhs.Ptr(), (const char*)aRhs.Ptr(), len);
145 return k != 0 ? k : ll - rl;
148 GLDEF_C TInt MultiProperty(TInt (*aHandler)(TAny* aObj, const char*), TAny* aPtr, const char* aProperty)
150 const char* value = Property::GetString(aProperty);
155 TInt r = aHandler(aPtr, value);
158 const char* ev = strchr(value, ';');
166 class DWinsGuiPowerHandler : public DPowerHandler
168 public: // from DPowerHandler
169 void PowerDown(TPowerState);
172 static DWinsGuiPowerHandler* New();
175 void ScreenOn(TInt aScreen);
176 void ScreenOff(TInt aScreen);
178 DWinsGuiPowerHandler();
179 TBool ProcessEvent(const TRawEvent* aEvent);
180 TBool ProcessEventDfc(const TRawEvent* aEvent);
184 static DWinsGuiPowerHandler* WinsGuiPowerHandler;
186 _LIT(KWinsGuiName, "WinsGui");
188 DWinsGuiPowerHandler* DWinsGuiPowerHandler::New()
190 DWinsGuiPowerHandler* self = new DWinsGuiPowerHandler();
198 DWinsGuiPowerHandler::DWinsGuiPowerHandler() : DPowerHandler(KWinsGuiName)
202 void DWinsGuiPowerHandler::ScreenOff()
204 for(TInt ix=0;ix<systemIni->iScreens.Count();ix++)
208 void DWinsGuiPowerHandler::ScreenOn()
210 for(TInt ix=0;ix<systemIni->iScreens.Count();ix++)
214 void DWinsGuiPowerHandler::ScreenOff(TInt aScreen)
216 PostMessageA(TheWin[aScreen], WM_EMUL_POWER_ON, FALSE, NULL);
217 systemIni->iScreens[aScreen]->iScreenOff = ETrue;
220 void DWinsGuiPowerHandler::ScreenOn(TInt aScreen)
222 PostMessageA(TheWin[aScreen], WM_EMUL_POWER_ON, TRUE, NULL);
223 systemIni->iScreens[aScreen]->iScreenOff = EFalse;
226 void DWinsGuiPowerHandler::PowerDown(TPowerState aState)
228 if (aState == EPwStandby)
235 void DWinsGuiPowerHandler::PowerUp()
242 // called in the interrupt context
243 TBool DWinsGuiPowerHandler::ProcessEvent(const TRawEvent* aEvent)
249 if ((aEvent->Type() == TRawEvent::EKeyDown))
251 Wins::Self() -> AssertWakeupSignal();
259 TBool DWinsGuiPowerHandler::ProcessEventDfc(const TRawEvent* aEvent)
261 if (aEvent->Type() == TRawEvent::EKeyDown)
263 Wins::Self() -> WakeupEvent();
264 if (aEvent->ScanCode() == EStdKeyF5)
266 // Simulate a media change interrupt (media removed)
267 Wins::MediaChangeCallBack();
268 *Wins::MediaDoorOpenPtr()=ETrue;
272 if (aEvent->ScanCode() == EStdKeyF8)
275 v.Set(TRawEvent::ECaseClose);
280 if (aEvent->ScanCode() == EStdKeyF8)
283 v.Set(TRawEvent::ECaseClose);
288 if (aEvent->ScanCode() == EStdKeyOff)
293 if (aEvent->ScanCode() == EStdKeyF10)
296 v.Set(TRawEvent::ESwitchOff);
301 if (aEvent->ScanCode() == EStdKeyF11)
304 v.Set(TRawEvent::ECaseOpen);
310 else if (aEvent->Type() == TRawEvent::EKeyUp)
312 if (aEvent->ScanCode() == EStdKeyF10)
316 if (aEvent->ScanCode() == EStdKeyF5)
318 // Simulate a media change interrupt (media Present)
319 *Wins::MediaDoorOpenPtr()=EFalse;
333 void Add(const TRawEvent& aEvent);
335 static void Dfc(TAny* aPtr);
344 :iDfc(&EventQ::Dfc, this, Kern::DfcQue0(), 6), iTail(iQ)
348 void EventQ::Add(const TRawEvent& aEvent)
351 if (WinsGuiPowerHandler->ProcessEvent(&aEvent))
357 TRawEvent* pE = iTail;
358 if (pE != &iQ[ESize])
368 void EventQ::Dfc(TAny* aPtr)
370 static_cast<EventQ*>(aPtr)->Empty();
382 if (!WinsGuiPowerHandler->ProcessEventDfc(pE))
385 irq = NKern::DisableAllInterrupts();
388 NKern::RestoreInterrupts(irq);
391 NKern::RestoreInterrupts(irq);
394 LOCAL_D EventQ TheEventQ;
399 VirtualKey::VirtualKey(const TInt aCommandData, const TEmulCommand aCommand) : iCommand(aCommand), iData(aCommandData)
403 TBool VKRect::Contains(TInt aX, TInt aY) const
405 return (aX >= iLeft && aX < iRight && aY >= iTop && aY < iBottom);
408 VKRect::VKRect(const TInt aCommandData, const TEmulCommand aCommand, TInt aX, TInt aY, TInt aWidth, TInt aHeight) :
409 VirtualKey(aCommandData, aCommand)
413 iRight = aX + aWidth;
414 iBottom = aY + aHeight;
419 void VKRect::Draw(HDC aHdc,COLORREF aColor) const
422 pen=CreatePen(PS_SOLID, 2, aColor);
423 SelectObject(aHdc, pen);
426 MoveToEx(aHdc, (int)iLeft, (int)iTop, &point);
427 LineTo(aHdc, (int)iLeft, (int)iBottom);
428 LineTo(aHdc, (int)iRight, (int)iBottom);
429 LineTo(aHdc, (int)iRight, (int)iTop);
430 LineTo(aHdc, (int)iLeft, (int)iTop);
434 KeyCombination::KeyCombination(const TInt aCommandData, TEmulCommand aCommand):
438 for (TInt i=0;i<KMaxHotKeyCombinationLength;i++)
440 iCombination[i]=EStdKeyNull;
444 TBool KeyCombination::CheckCombinationPressed()
446 for (TInt j=0;(j<KMaxHotKeyCombinationLength && iCombination[j]!=0);j++)
448 if (GetAsyncKeyState(MapVirtualKey(iCombination[j],1))>=0)//if at least one key is not pressed, we return false
454 TBool KeyCombination::AddKey(TStdScanCode aKey)
457 for (i=0;i<KMaxHotKeyCombinationLength;i++)
459 if (iCombination[i]==EStdKeyNull)
462 if (KMaxHotKeyCombinationLength==i)
465 iCombination[i]=aKey;
471 DScreenProperties::DScreenProperties()
473 memset(this,0,sizeof(DScreenProperties));
474 iColorDepth=KDefaultColorDepth;
476 iViewport = TViewport(this);
480 LOCAL_C TInt MaskGceOnly(TInt aModeBits)
481 { //All HAL modes are now reported. The GCE may refuse to register the surfaces.
482 return aModeBits&KEmulModes; //previous useful settings: //(KEmulPixPerLong2|KEmulPixPerLong1); //|KEmulPixPerLong4;
485 LOCAL_C TInt BitsForSingleMode(TInt aModeColor)
486 { //only 1 bit should be set in aModeColor
489 case KEmulGray2: return 1;
490 case KEmulGray4: return 2;
491 case KEmulGray16: return 4;
492 case KEmulGray256: return 8;
493 case KEmulColor16: return 4;
494 case KEmulColor256: return 8;
495 case KEmulColor4K: return 12;
496 case KEmulColor64K: return 16;
497 case KEmulColor16M: return 24;
503 DScreenProperties::~DScreenProperties()
507 TWindowState DScreenProperties::GetWindowState()
510 state.iWinPlace = iWinPlace;
511 state.iFlipstate = iScreenRotation;
512 state.iXoffset = iViewport.GetViewportOffsetX();
513 state.iYoffset = iViewport.GetViewportOffsetY();
517 TInt DScreenProperties::SetupProperties(TInt aConf, TInt aScreen)
521 // Calculate maximum dimensions
522 TInt configurations = Property::GetInt("ConfigCount", 0);
523 if (configurations == 0)
526 TInt count, screenWidth, screenHeight, physicalScreenWidth, physicalScreenHeight;
527 for (count = 0; count < configurations; ++count)
529 wsprintfA(property, "Configuration[%d][%d]ScreenWidth", count, aScreen);
530 screenWidth = Property::GetInt(property, KScreenWidth);
531 screenWidth = (screenWidth + 3) & ~3;
532 if (screenWidth > iMaxScreenWidth)
533 iMaxScreenWidth = screenWidth;
534 wsprintfA(property, "Configuration[%d][%d]ScreenHeight", count, aScreen);
535 screenHeight = Property::GetInt(property, KScreenHeight);
536 screenHeight = (screenHeight + 3) & ~3;
537 if (screenHeight > iMaxScreenHeight)
538 iMaxScreenHeight = screenHeight;
540 wsprintfA(property, "Configuration[%d][%d]PhysicalScreenWidth", count, aScreen);
541 physicalScreenWidth = Property::GetInt(property);
542 if (physicalScreenWidth > iMaxPhysicalScreenWidth)
543 iMaxPhysicalScreenWidth = physicalScreenWidth;
544 wsprintfA(property, "Configuration[%d][%d]PhysicalScreenHeight", count, aScreen);
545 physicalScreenHeight = Property::GetInt(property);
546 if (physicalScreenHeight > iMaxPhysicalScreenHeight)
547 iMaxPhysicalScreenHeight = physicalScreenHeight;
550 // Read figures for current configuration
551 TInt givenWidth, givenHeight;
552 wsprintfA(property, "Configuration[%d][%d]ScreenWidth",aConf,aScreen);
553 givenWidth = Property::GetInt(property, KScreenWidth);
554 iScreenWidth = (givenWidth + 3) & ~3;
555 wsprintfA(property, "Configuration[%d][%d]ScreenHeight",aConf,aScreen);
556 givenHeight = Property::GetInt(property, KScreenHeight);
557 iScreenHeight = (givenHeight + 3) & ~3;
558 // Width of screen should be multiple number of 4 pixels.
559 if (givenWidth & 3 || givenHeight & 3)
561 Kern::Printf("Width and Height of Screen should be multiple number of 4 pixels.\n"
562 "\tWidth of screen[%d] set to: %d\n\tHeight of screen[%d] set to: %d",
563 aScreen, iScreenWidth, aScreen, iScreenHeight);
567 wsprintfA(property, "Configuration[%d][%d]PhysicalScreenWidth",aConf,aScreen);
568 iPhysicalScreenWidth = Property::GetInt(property);
569 wsprintfA(property, "Configuration[%d][%d]PhysicalScreenHeight",aConf,aScreen);
570 iPhysicalScreenHeight = Property::GetInt(property);
572 wsprintfA(property, "Configuration[%d][%d]ScreenOffsetX",aConf,aScreen);
573 iScreenOffsetX = Property::GetInt(property, KScreenOffsetX);
574 wsprintfA(property, "Configuration[%d][%d]ScreenOffsetY",aConf,aScreen);
575 iScreenOffsetY = Property::GetInt(property, KScreenOffsetY);
577 wsprintfA(property, "Configuration[%d][%d]CompositionBuffers",aConf,aScreen);
578 iCompositionBuffers = Property::GetInt(property, KCompositionBuffers);
580 wsprintfA(property, "Configuration[%d][%d]RefreshRateHz",aConf,aScreen);
581 iRefreshRateHz = Property::GetInt(property, KRefreshRateHz);
584 wsprintfA(property, "Configuration[%d][%d]ColorDepth",aConf,aScreen);
585 const char* colors = Property::GetString(property);
589 const char* end = colors;
592 const char* beg = skipws(end);
598 if (_strnicmp("Gray2",beg,end-beg) == 0)
600 colorDepth|=KEmulGray2|KEmulIsBitMask;
602 else if (_strnicmp("Gray4",beg,end-beg) == 0)
604 colorDepth|=KEmulGray4|KEmulIsBitMask;
606 else if (_strnicmp("Gray16",beg,end-beg) == 0)
608 colorDepth|=KEmulGray16|KEmulIsBitMask;
610 else if (_strnicmp("Gray256",beg,end-beg) == 0)
612 colorDepth|=KEmulGray256|KEmulIsBitMask;
614 else if (_strnicmp("Color16",beg,end-beg) == 0)
616 colorDepth|=KEmulColor16|KEmulIsBitMask;
618 else if (_strnicmp("Color256",beg,end-beg) == 0)
620 colorDepth|=KEmulColor256|KEmulIsBitMask;
622 else if (_strnicmp("Color4K",beg,end-beg) == 0)
624 colorDepth|=KEmulColor4K|KEmulIsBitMask;
626 else if (_strnicmp("Color64K",beg,end-beg) == 0)
628 colorDepth|=KEmulColor64K|KEmulIsBitMask;
630 else if (_strnicmp("Color16M",beg,end-beg) == 0)
632 colorDepth|=KEmulColor16M|KEmulIsBitMask;
637 iColorDepth = colorDepth;
640 //multiple mode support is currently only for GCE.
641 //I fill this array in before knowing if GCE will be instanced.
642 if (iColorDepth&KEmulIsBitMask)
644 //iModeDepths is only used by GCE
645 TInt colorDepth=MaskGceOnly(iColorDepth);
647 for (TInt i=1;i!=KEmulIsBitMask;i+=i)
649 iModeDepths[setMode++]=BitsForSingleMode(i);
651 iModeDepths[setMode++]=0; //a bit width of 0 is illegal
655 iModeDepths[0]=iColorDepth;
657 iModeDepths[1]=0; //a bit width of 0 is illegal
660 wsprintfA(property, "Configuration[%d][%d]FasciaBitmap",aConf,aScreen);
661 const char* fascia = Property::GetString(property);
664 TInt len = strlen(fascia);
665 //the path may have quotes at the start and end
666 //need to work out if this is an absolute or relative path
667 if (fascia[0] == '\"')
671 if (--len > 0 && fascia[len-1] == '\"')
674 char* p = iFasciaFileName;
675 if (fascia[0] != '\\' && (len < 3 || fascia[1] != ':'))
678 strcpy(p, Property::GetString("EmulatorDataPath"));
681 memcpy(p, fascia, len);
686 // default to machine name
687 strcpy(iFasciaFileName, Property::GetString("EmulatorDataPath"));
688 strcat(iFasciaFileName, Property::GetString("MachineName"));
689 strcat(iFasciaFileName, ".bmp");
694 TViewport::TViewport()
695 :iScreenProps(NULL),iViewportWidth(0), iViewportHeight(0), iViewportOffsetX(0), iViewportOffsetY(0)
699 TViewport::TViewport(DScreenProperties* aScreenProps)
700 :iScreenProps(aScreenProps),iViewportWidth(0), iViewportHeight(0), iViewportOffsetX(0), iViewportOffsetY(0)
703 TViewport::~TViewport()
709 Changes the logical position of the viewport within the input area
710 of the emulator screen. The method may adjust the position so that
711 the viewport stays within the input area.
712 @param aPosition The new Y position of the top left hand corner of the viewport.
713 @param aHwnd The window associated with the viewport
715 void TViewport::ScrollToY(TInt aPosition, HWND aHwnd)
718 SCROLLINFO scrollinfo;
719 scrollinfo.cbSize=sizeof(scrollinfo);
722 scrollinfo.fMask=SIF_POS;
723 GetScrollInfo(aHwnd, SB_VERT, &scrollinfo);
724 TInt oldY=scrollinfo.nPos;
730 else if( (aPosition+GetViewportHeight())>GetMaxHeight())
732 scrollinfo.nPos = max(0,GetMaxHeight() - GetViewportHeight() );
736 scrollinfo.nPos=aPosition;
739 SetViewportOffsetY(scrollinfo.nPos);
740 scrollinfo.fMask=SIF_POS;
741 SetScrollInfo(aHwnd,SB_VERT, &scrollinfo, TRUE );
742 ScrollWindowEx(aHwnd, 0, oldY-scrollinfo.nPos, 0, 0, NULL, NULL, SW_INVALIDATE);
744 UpdateChildPos(aHwnd);
748 As for ScrollToY but for the X direction
750 void TViewport::ScrollToX(TInt aPosition, HWND aHwnd)
752 SCROLLINFO scrollinfo;
753 scrollinfo.cbSize=sizeof(scrollinfo);
756 scrollinfo.fMask=SIF_POS;
757 GetScrollInfo(aHwnd, SB_HORZ, &scrollinfo);
758 TInt oldX=scrollinfo.nPos;
764 else if( (aPosition+GetViewportWidth())>GetMaxWidth())
766 scrollinfo.nPos = max(0,GetMaxWidth() - GetViewportWidth() );
770 scrollinfo.nPos=aPosition;
773 SetViewportOffsetX(scrollinfo.nPos);
774 scrollinfo.fMask=SIF_POS;
775 SetScrollInfo(aHwnd,SB_HORZ, &scrollinfo, TRUE );
776 ScrollWindowEx(aHwnd, oldX-scrollinfo.nPos, 0, 0, 0, NULL, NULL, SW_INVALIDATE);
778 UpdateChildPos(aHwnd);
781 //Forward declaration
782 LOCAL_C TInt ScreenFromHWND(HWND aHwnd,HWND* pWin);
785 Move the child window to it's correct position.
787 @param aHwnd The HWND of the parent window
789 void TViewport::UpdateChildPos(HWND aHwnd)
791 TInt screenNumber = ::ScreenFromHWND(aHwnd,TheWin);
792 HWND childWin = TheChildWin[screenNumber];
794 switch (iScreenProps->iScreenRotation)
796 case EEmulatorFlipRestore:
799 iScreenProps->iScreenOffsetX - GetViewportOffsetX(),
800 iScreenProps->iScreenOffsetY - GetViewportOffsetY(),
801 iScreenProps->iScreenWidth,
802 iScreenProps->iScreenHeight,
806 case EEmulatorFlipInvert:
809 iScreenProps->iXYInputWidth-(iScreenProps->iScreenOffsetX+iScreenProps->iScreenWidth) - GetViewportOffsetX(),
810 iScreenProps->iXYInputHeight-(iScreenProps->iScreenOffsetY+iScreenProps->iScreenHeight) - GetViewportOffsetY(),
811 iScreenProps->iScreenWidth,
812 iScreenProps->iScreenHeight,
816 case EEmulatorFlipLeft:
819 iScreenProps->iScreenOffsetY - GetViewportOffsetX(),
820 iScreenProps->iXYInputWidth-(iScreenProps->iScreenOffsetX+iScreenProps->iScreenWidth)- GetViewportOffsetY(),
821 iScreenProps->iScreenHeight,
822 iScreenProps->iScreenWidth,
826 case EEmulatorFlipRight:
829 iScreenProps->iXYInputHeight-(iScreenProps->iScreenOffsetY+iScreenProps->iScreenHeight) - GetViewportOffsetX(),
830 iScreenProps->iScreenOffsetX - GetViewportOffsetY(),
831 iScreenProps->iScreenHeight,
832 iScreenProps->iScreenWidth,
841 Update the range of the horizontal scrollbar,
842 to take account of the current viewport width.
844 @param aHwnd The window to be updated
846 void TViewport::UpdateScrollBarH(HWND aHwnd)
849 SCROLLINFO scrollinfoHor;
850 scrollinfoHor.cbSize=sizeof(scrollinfoHor);
851 scrollinfoHor.fMask=SIF_RANGE|SIF_PAGE;
852 scrollinfoHor.nMin=0;
853 scrollinfoHor.nMax= GetMaxWidth()-1;
856 TInt newPage = GetViewportWidth() ;
857 TBool redraw=EFalse; //redraw window if a resize has caused a scrollbar to disappear and reveal image.
858 if ( newPage>= scrollinfoHor.nMax -GetSystemMetrics(SM_CXVSCROLL)
859 && newPage < scrollinfoHor.nMax+1)
862 newPage=GetMaxWidth();
865 scrollinfoHor.nPage= newPage;
867 SetScrollInfo(aHwnd,SB_HORZ, &scrollinfoHor, TRUE );
870 ScrollToX(0, aHwnd); //in case egde of fascia was against edge of vertical scrollbar
871 InvalidateRect(aHwnd, NULL, TRUE);
876 Update the range of the vertical scrollbar,
877 to take account of the current viewport width.
879 @param aHwnd The window to be updated
881 void TViewport::UpdateScrollBarV(HWND aHwnd)
883 SCROLLINFO scrollinfoVer;
884 scrollinfoVer.cbSize=sizeof(scrollinfoVer);
885 scrollinfoVer.fMask=SIF_RANGE|SIF_PAGE;
886 scrollinfoVer.nMin=0;
887 scrollinfoVer.nMax= GetMaxHeight()-1;
889 TInt newPage = GetViewportHeight() ;
890 TBool redraw=EFalse; //redraw window if a resize has caused a scrollbar to disappear and reveal image.
891 if ( newPage>= scrollinfoVer.nMax -GetSystemMetrics(SM_CYHSCROLL)
892 && newPage < scrollinfoVer.nMax+1)
895 newPage=GetMaxHeight();
897 scrollinfoVer.nPage= newPage;
899 SetScrollInfo(aHwnd,SB_VERT, &scrollinfoVer, TRUE );
902 ScrollToY(0, aHwnd); //in case egde of fascia was against edge of vertical scrollbar
903 InvalidateRect(aHwnd, NULL, TRUE);
908 Returns the max width for the viewport window (non-client area) so that it
909 may be bounded. Takes account of scrollbar.
913 TInt TViewport::GetMaxWindowWidth() const
916 RECT rect = {0,0,0,0};
918 switch(iScreenProps->iScreenRotation)
920 case EEmulatorFlipRestore:
921 case EEmulatorFlipInvert:
923 rect.right=iScreenProps->iXYInputWidth;
924 rect.bottom=iScreenProps->iXYInputHeight;
927 case EEmulatorFlipLeft:
928 case EEmulatorFlipRight:
930 rect.right=iScreenProps->iXYInputHeight;
931 rect.bottom=iScreenProps->iXYInputWidth;
935 AdjustWindowRect(//take account of window decorations
942 return (rect.right-rect.left);
946 Returns the max height for the viewport window (non-client area) so that it
947 may be bounded. Takes account of scrollbar.
951 TInt TViewport::GetMaxWindowHeight() const
954 RECT rect ={0,0,0,0};
956 switch(iScreenProps->iScreenRotation)
958 case EEmulatorFlipRestore:
959 case EEmulatorFlipInvert:
961 rect.right=iScreenProps->iXYInputWidth;
962 rect.bottom=iScreenProps->iXYInputHeight;
965 case EEmulatorFlipLeft:
966 case EEmulatorFlipRight:
968 rect.right=iScreenProps->iXYInputHeight;
969 rect.bottom=iScreenProps->iXYInputWidth;
973 AdjustWindowRect(//take account of window decorations
978 return (rect.bottom-rect.top);
982 Returns the maximum width for the viewport (client area only).
983 Allowing for the orientation of the emulator.
987 TInt TViewport::GetMaxWidth() const
990 switch(iScreenProps->iScreenRotation)
992 case EEmulatorFlipRestore:
993 case EEmulatorFlipInvert:
995 width = iScreenProps->iXYInputWidth;
998 case EEmulatorFlipLeft:
999 case EEmulatorFlipRight:
1001 width = iScreenProps->iXYInputHeight;
1010 Returns the maximum height for the viewport (client area only).
1011 Allowing for the orientation of the emulator.
1015 TInt TViewport::GetMaxHeight() const
1018 switch(iScreenProps->iScreenRotation)
1020 case EEmulatorFlipRestore:
1021 case EEmulatorFlipInvert:
1023 height = iScreenProps->iXYInputHeight;
1026 case EEmulatorFlipLeft:
1027 case EEmulatorFlipRight:
1029 height = iScreenProps->iXYInputWidth;
1039 Sets the X offset of the viewport from the edge of the input area
1040 @param aOffset The X offset
1042 void TViewport::SetViewportOffsetX(TInt aOffset)
1044 iViewportOffsetX = aOffset;
1048 Sets the Y offset of the viewport from the edge of the input area
1049 @param aOffset The Y offset
1051 void TViewport::SetViewportOffsetY(TInt aOffset)
1053 iViewportOffsetY = aOffset;
1056 TInt TViewport::GetViewportOffsetX() const
1058 return iViewportOffsetX;
1060 TInt TViewport::GetViewportOffsetY() const
1062 return iViewportOffsetY;
1066 Sets the viewport width, this is equal to the width
1067 of the window's client area
1068 @param aWidth The width
1070 void TViewport::SetViewportWidth(TInt aWidth)
1072 iViewportWidth=aWidth;
1076 Sets the viewport height, this is equal to the height
1077 of the window's client area
1078 @param aHeight The height
1080 void TViewport::SetViewportHeight(TInt aHeight)
1082 iViewportHeight=aHeight;
1085 TInt TViewport::GetViewportWidth() const
1087 return iViewportWidth;
1089 TInt TViewport::GetViewportHeight() const
1091 return iViewportHeight;
1101 /// Returns the current mode's depth. Remember current mode is never set!
1102 TUint DWinsUi::ColorDepth(TInt aScreenNumber)
1105 VideoInfo(aScreenNumber, info);
1106 return info.iBitsPerPixel;
1109 TInt DWinsUi::SetFlip(TEmulatorFlip aFlip, TInt aScreenNumber)
1111 if(TUint(aScreenNumber)>=TUint(systemIni->iScreens.Count()))
1112 return KErrArgument;
1113 int r1 = PostMessageA(TheChildWin[aScreenNumber],WM_FLIP_MESSAGE,(TUint)aFlip,NULL);
1114 return r1 ? KErrNone : KErrGeneral;
1117 void DWinsUi::Info(TVariantInfoV01& aInfo)
1119 aInfo.iLedCapabilities=0x3;
1122 HWND DWinsUi::HWnd()
1124 return TheControlWin;
1127 TInt DWinsUi::SetupProperties(TInt aId)
1130 // load UI settings from the emulator properties
1134 TInt screens = Property::GetInt("[screens]", 1);
1136 for (TInt x = 0; x < screens; ++x)
1138 DScreenProperties * pScr = new DScreenProperties();
1140 return KErrNoMemory;
1142 TInt ret = pScr->SetupProperties(aId,x);
1143 if (KErrNone == ret)
1144 ret = iScreens.Append(pScr);
1146 if (KErrNone != ret)
1154 wsprintfA(property, "Configuration[%d]LedSize",aId);
1155 iLedSize = Property::GetInt(property, KLedSize);
1156 wsprintfA(property, "Configuration[%d]LedArrangeVertically",aId);
1157 iLedVertical = Property::GetBool(property, KLedVertical);
1158 wsprintfA(property, "Configuration[%d]LedArrangeHorizontally",aId);
1159 if (Property::GetBool(property))
1160 iLedVertical = EFalse;
1161 wsprintfA(property, "Configuration[%d]LedOffsetX",aId);
1162 iLedOffsetX = Property::GetInt(property, KLedLeft);
1163 wsprintfA(property, "Configuration[%d]LedOffsetY",aId);
1164 iLedOffsetY = Property::GetInt(property, KLedTop);
1165 wsprintfA(property, "Configuration[%d]LedGap",aId);
1166 iLedGap = Property::GetInt(property, KLedGap);
1168 wsprintfA(property, "Configuration[%d]PointerType",aId);
1169 const char* pointer = Property::GetString(property, "Pen");
1170 if (_stricmp(pointer, "None") == 0)
1172 iPointerType=_S8("NONE");
1173 iXYInputType=EXYInputNone;
1175 else if (_stricmp(pointer,"Pen") == 0)
1177 iPointerType=_S8("PEN");
1178 iXYInputType=EXYInputPointer;
1180 else if (_stricmp(pointer,"Mouse") == 0)
1182 iPointerType=_S8("MOUSE");
1183 iXYInputType=EXYInputMouse;
1185 else if (_stricmp(pointer,"Delta-Mouse") == 0)
1187 iPointerType=_S8("MOUSE");
1188 iXYInputType=EXYInputDeltaMouse;
1191 return KErrArgument;
1193 wsprintfA(property, "Configuration[%d]DigitizerOffsetX",aId);
1194 iDigitizerOffsetX = Property::GetInt(property, -iScreens[0]->iScreenOffsetX);
1195 wsprintfA(property, "Configuration[%d]DigitizerOffsetY",aId);
1196 iDigitizerOffsetY = Property::GetInt(property, -iScreens[0]->iScreenOffsetY);
1197 wsprintfA(property, "Configuration[%d]DigitizerWidth",aId);
1198 iDigitizerWidth = Property::GetInt(property,-1);
1199 wsprintfA(property, "Configuration[%d]DigitizerHeight",aId);
1200 iDigitizerHeight = Property::GetInt(property,-1);
1201 wsprintfA(property, "Configuration[%d]DisableDigitizer",aId);
1202 iDigitizerEnabled = !Property::GetBool(property);
1203 // To enable the multitouch
1204 wsprintfA(property, "EnableMultiTouch");
1205 iMultiTouchEnabled = Property::GetBool(property,EFalse);
1206 wsprintfA(property, "SYMBIAN_BASE_USE_GCE");
1207 iGCEEnabled = Property::GetBool(property,EFalse);
1208 wsprintfA(property, "MultiTouchProximityStep");
1209 iMultiTouchProximityStep = Property::GetInt(property,-1);
1210 wsprintfA(property, "MultiTouchPressureStep");
1211 iMultiTouchPressureStep = Property::GetInt(property,-1);
1213 strcpy(iSysIniFileName, Property::GetString("EmulatorDataPath"));
1214 strcat(iSysIniFileName, "emulator\\");
1215 if (!Emulator::CreateAllDirectories(iSysIniFileName))
1216 return Emulator::LastError();
1217 strcat(iSysIniFileName, Property::GetString("MachineName"));
1218 strcat(iSysIniFileName, ".sys.ini");
1220 TInt r = iKeyboard.Init(aId);
1224 wsprintfA(property, "Configuration[%d]VirtualKey",aId);
1225 r = MultiProperty(&DWinsUi::DoDefineVirtualKey, this, property);
1230 wsprintfA(property, "Configuration[%d]NoVersionInfo",aId);
1231 iDisplayVersionInfo = !Property::GetBool(property);
1233 wsprintfA(property, "Configuration[%d]WindowTitle",aId);
1234 const char * p = Property::GetString(property);
1235 if (p && (strlen(p) <= KMaxNameSize))
1236 strcpy(iWindowTitle, p);
1238 strcpy(iWindowTitle, DefaultWindowTitle);
1240 if (iDisplayVersionInfo)
1242 TInt wtLen = strlen(iWindowTitle);
1243 TInt vtLen = strlen(VersionText);
1244 if ((wtLen + vtLen) > KMaxNameSize)
1245 iWindowTitle[KMaxNameSize-vtLen] = '\0';
1246 strcat(iWindowTitle, VersionText);
1249 wsprintfA(property, "Configuration[%d]OnActivation",aId);
1250 pointer = Property::GetString(property);
1251 //example OnActivation 270 EKeyScreenDimension1
1252 //params are rotation(int) and key(string)
1257 //skip any white space
1258 const char* beg = skipws(pointer);
1261 long rotation = strtol(beg, &next, 0);
1263 return KErrArgument;
1268 iScreens[0]->iScreenRotation = EEmulatorFlipRestore;
1271 iScreens[0]->iScreenRotation = EEmulatorFlipRight;
1274 iScreens[0]->iScreenRotation = EEmulatorFlipInvert;
1277 iScreens[0]->iScreenRotation = EEmulatorFlipLeft;
1287 //beg should now point to the keycode
1288 TInt key = iKeyboard.GetEPOCKeyCode(TPtrC8((const TUint8*)beg, strlen(beg)));
1289 if (key == KErrNotFound)
1291 iInitialFlipMsg = key;
1294 //EmulatorControl messages are a bit like virtual keys
1295 wsprintfA(property, "Configuration[%d]EmulatorControl",aId);
1296 r = MultiProperty(&DWinsUi::DoDefineEmulatorControl, this, property);
1300 wsprintfA(property, "Configuration[%d]EmulatorControlHotKey",aId);
1301 r = MultiProperty(&DWinsUi::DoDefineEmulatorControlHotKey, this, property);
1308 TInt DWinsUi::NumberOfScreens()
1310 return iScreens.Count();
1314 Return the highest bit depth from an emulator mode mask.
1315 @param aModeMask A bitwise combination of KEmul... display mode mask values.
1316 @return A color depth in bits per pixel.
1318 LOCAL_C TInt MaximumBitDepthFromMask(TInt aModeMask)
1320 // Choose the highest bits per pixel based on the display mode mask.
1321 if (aModeMask & KEmulColor16M)
1325 if (aModeMask & KEmulColor64K)
1329 if (aModeMask & KEmulColor4K)
1334 // Lower bit depths are not supported, so use the default
1340 Return the TDisplayRotation corresponding to the given TEmulatorFlip.
1341 @param aFlip A screen rotation as a TEmulatorFlip.
1342 @return The screen rotation as a TDisplayRotation.
1344 LOCAL_C RDisplayChannel::TDisplayRotation FlipToDisplayRotation(TEmulatorFlip aFlip)
1348 case EEmulatorFlipLeft:
1349 return RDisplayChannel::ERotation90CW;
1350 case EEmulatorFlipInvert:
1351 return RDisplayChannel::ERotation180;
1352 case EEmulatorFlipRight:
1353 return RDisplayChannel::ERotation270CW;
1355 return RDisplayChannel::ERotationNormal;
1359 TInt DWinsUi::SetDisplayChannel(TInt aScreenNumber, DDisplayChannel* aDisplay)
1361 return systemIni->SetDisplayChannelImpl(aScreenNumber,aDisplay);
1365 TInt DWinsUi::SetDisplayChannelImpl(TInt aScreenNumber, DDisplayChannel* aDisplay)
1367 if (TUint(aScreenNumber) >= TUint(NumberOfScreens()))
1369 // Screen number is either negative or too big.
1370 return KErrArgument;
1374 HWND hWnd = TheChildWin[aScreenNumber];
1375 TBufferSet& buffer = masterIni->iBufferSet[aScreenNumber];
1379 // Display driver connecting
1380 DScreenProperties* screen = iScreens[aScreenNumber];
1381 RDisplayChannel::TDisplayInfo info;
1383 TInt pixelBytes = 2;
1384 info.iBitsPerPixel = MaximumBitDepthFromMask(screen->iColorDepth);
1386 switch (info.iBitsPerPixel)
1388 case 12: // XRGB4444
1389 info.iPixelFormat = EUidPixelFormatXRGB_4444;
1392 info.iPixelFormat = EUidPixelFormatRGB_565;
1395 // Force anything else to packed RGB888
1397 info.iBitsPerPixel = 24;
1398 info.iPixelFormat = EUidPixelFormatXRGB_8888;
1402 TInt width = screen->iMaxScreenWidth;
1403 TInt height = screen->iMaxScreenHeight;
1405 info.iRefreshRateHz = screen->iRefreshRateHz;
1406 info.iAvailableRotations = RDisplayChannel::ERotationNormal | RDisplayChannel::ERotation90CW |
1407 RDisplayChannel::ERotation180 | RDisplayChannel::ERotation270CW;
1408 info.iNormal.iWidth = width;
1409 info.iNormal.iHeight = height;
1410 // Windows requires rounding up to 4-bytes words
1411 info.iNormal.iOffsetBetweenLines = _ALIGN_UP(width * pixelBytes, 4);
1412 info.iFlipped.iWidth = height;
1413 info.iFlipped.iHeight = width;
1414 // Windows requires rounding up to 4-bytes words
1415 info.iFlipped.iOffsetBetweenLines = _ALIGN_UP(height * pixelBytes, 4);
1418 //ensure legacy buffer is large enough for all supported modes.
1419 //It would be a very strange setup for the max size to not be the max bpp,
1420 //but we don't know which mode is max bpp anyway!
1421 TVideoInfoV01 videoInfo;
1422 for (TInt mode=0,maxMode=screen->iMaxModes;mode<maxMode;mode++)
1424 if (systemIni->VideoInfoForDisplayDriver(aScreenNumber,mode, videoInfo)) //can't actually fail currently
1426 TInt dwSize=videoInfo.iOffsetToFirstPixel+videoInfo.iOffsetBetweenLines*videoInfo.iSizeInPixels.iHeight;
1432 Fault(EGuiVideoInfoUnavailable);
1434 //rotated mode may use more RAM?? Height may be >Width or may not be a multiple of stride quantum
1435 if (systemIni->VideoInfoForDisplayDriver(aScreenNumber,mode|KModeFlagFlipped, videoInfo)) //can't actually fail currently
1437 TInt dwSize=videoInfo.iOffsetToFirstPixel+videoInfo.iOffsetBetweenLines*videoInfo.iSizeInPixels.iWidth;
1445 Fault(EGuiVideoInfoUnavailable);
1449 masterIni->iMaxSizeInBytes = maxSize;
1450 if (__e32_atomic_add_ord32(&buffer.iDisplayDriverCount, 1) == 0)
1452 // First driver to connect, allocate frame buffers.
1453 // +1 frame buffer is ui legacy buffer at [0], so does need to take account of stride and offset
1454 r = masterIni->AllocateFrameBuffers(aScreenNumber, screen->iCompositionBuffers + 1, maxSize);
1459 buffer.iScreenBuffer.iDisplayBufferOffset = 0;
1460 masterIni->iBufferSet[aScreenNumber].iDisplayChannel = aDisplay;
1461 masterIni->InitBitmapHeader(*screen, &buffer.iInfo);
1462 masterIni->InitBufferFormat(*screen, buffer.iBufferFormat);
1463 if(systemIni->VideoInfoForDisplayDriver(aScreenNumber,screen->iCurrentMode, videoInfo, ETrue))
1465 r = aDisplay->Initialize(info,
1466 FlipToDisplayRotation(screen->iScreenRotation),
1467 hWnd, buffer.iScreenBuffer.iFrameBuffers,
1468 buffer.iScreenBuffer.iMemChunks,
1470 videoInfo.iSizeInPixels,videoInfo.iSizeInTwips,
1471 masterIni->iSupportedPixelFormatTable,
1472 masterIni->iSupportedPixelFormatTableSize,
1473 buffer.iBufferFormat);
1477 Fault(EGuiVideoInfoUnavailable);
1481 if (r != KErrNone && __e32_atomic_tas_ord32(&buffer.iDisplayDriverCount, 1, -1, 0) == 1)
1483 // Release any that were allocated
1484 masterIni->ReleaseFrameBuffers(aScreenNumber);
1489 // Display driver disconnected
1490 if (__e32_atomic_tas_ord32(&buffer.iDisplayDriverCount, 1, -1, 0) == 1)
1492 // All drivers disconnected, deallocate memory.
1493 masterIni->ReleaseFrameBuffers(aScreenNumber);
1501 void DWinsUi::SetVirtualKey(const TBool aProcessing, const TInt aCommandData, const TEmulCommand aCommand)
1503 iProcessingVirtualKey = aProcessing;
1504 iFakedVirtualKey = aCommandData;
1505 iVirtualKeyCommand = aCommand;
1508 TBool DWinsUi::WasVirtualKey(TInt& aCommandData, TEmulCommand& aCommand)
1510 if (iProcessingVirtualKey)
1513 aCommandData = iFakedVirtualKey;
1514 aCommand = iVirtualKeyCommand;
1516 return iProcessingVirtualKey;
1520 TInt DWinsUi::DoDefineEmulatorControl(TAny* aPtr, const char* aValue)
1522 return static_cast<DWinsUi*>(aPtr)->DefineEmulatorControl(aValue);
1526 TInt DWinsUi::DefineEmulatorControl(const char* aValue)
1529 //example EmulatorControl SelectConfig 2 rect 223,640 29,22
1530 //example EmulatorControl NextConfig rect 223,640 29,22
1531 const char* beg = skipws(aValue);
1532 const char* end = skiptok(beg);
1533 TInt err = KErrNone;
1535 TEmulCommand command = ENoCommand;
1537 if (_strnicmp(beg, "SelectConfig", end-beg) == 0)
1539 //get the int param which is the config to switch to
1542 data = strtol(beg, &e,0);
1546 command = ESelectConfig;
1548 else if(_strnicmp(beg, "NextConfig", end-beg) == 0)
1551 command = ENextConfig;
1556 if (err != KErrNone)
1562 if (end - beg != 4 || _strnicmp(beg, "rect", 4) != 0)
1563 return KErrArgument;
1565 // get the parameters
1568 TInt x = strtol(beg, &end2, 10);
1569 if (beg == end2 || *end2++ != ',')
1570 return KErrArgument;
1572 TInt y = strtol(beg, &end2, 10);
1574 return KErrArgument;
1576 TInt w = strtol(beg, &end2, 10);
1577 if (beg == end2 || *end2++ != ',')
1578 return KErrArgument;
1580 TInt h = strtol(beg, &end2, 10);
1582 return KErrArgument;
1584 VKRect* pRect = new VKRect(data, command, x, y, w, h);
1586 return KErrNoMemory;
1587 return iVirtualKeys.Append(pRect);
1592 TInt DWinsUi::DoDefineVirtualKey(TAny* aPtr, const char* aValue)
1594 return static_cast<DWinsUi*>(aPtr)->DefineVirtualKey(aValue);
1597 TInt DWinsUi::DefineVirtualKey(const char* aValue)
1599 // Get the key to map
1600 const char* beg = skipws(aValue);
1601 const char* end = skiptok(beg);
1602 TInt key = iKeyboard.GetEPOCKeyCode(TPtrC8((const TUint8*)beg, end-beg));
1603 if (key == KErrNotFound)
1609 if (end - beg != 4 || _strnicmp(beg, "rect", 4) != 0)
1610 return KErrArgument;
1612 // get the parameters
1615 TInt x = strtol(beg, &end2, 10);
1616 if (beg == end2 || *end2++ != ',')
1617 return KErrArgument;
1619 TInt y = strtol(beg, &end2, 10);
1621 return KErrArgument;
1623 TInt w = strtol(beg, &end2, 10);
1624 if (beg == end2 || *end2++ != ',')
1625 return KErrArgument;
1627 TInt h = strtol(beg, &end2, 10);
1629 return KErrArgument;
1631 VKRect* pRect = new VKRect(key, EKey, x, y, w, h);
1633 return KErrNoMemory;
1634 return iVirtualKeys.Append(pRect);
1638 LOCAL_C TInt readBitmapInfo(PBITMAPINFOHEADER aHeader, const char* aFileName)
1640 PBITMAPFILEHEADER pbmfh=NULL;
1641 PBITMAPINFOHEADER pbmih=NULL;
1644 HANDLE fh=CreateFileA(aFileName,GENERIC_READ,NULL,NULL,OPEN_EXISTING,NULL,NULL);
1645 if (!fh || fh==INVALID_HANDLE_VALUE)
1646 return KErrNotFound;
1650 // read in the bitmap file header. save the offset to bits.
1651 pbmfh = (PBITMAPFILEHEADER)LocalAlloc(LPTR, sizeof(BITMAPFILEHEADER));
1658 ReadFile(fh, (LPVOID)pbmfh, sizeof(BITMAPFILEHEADER), &bytesRead, NULL);
1659 bfOffBits=pbmfh->bfOffBits;
1661 // read in the bitmap info header and the color table right after it.
1662 pbmih = (PBITMAPINFOHEADER)LocalAlloc(LPTR, bfOffBits- sizeof(BITMAPFILEHEADER));
1668 ReadFile(fh, (LPVOID)pbmih, bfOffBits-sizeof(BITMAPFILEHEADER),&bytesRead,NULL);
1671 LocalFree(LocalHandle ((LPSTR)pbmih));
1672 LocalFree(LocalHandle ((LPSTR)pbmfh));
1677 HBITMAP readBitmap(HDC aHdc, const char* aFileName)
1679 // reads a BMP file from disk and returns a HBITMAP
1683 PBITMAPFILEHEADER pbmfh=NULL;
1684 PBITMAPINFOHEADER pbmih=NULL;
1689 HANDLE fh=CreateFileA(aFileName, GENERIC_READ, NULL, NULL, OPEN_EXISTING, NULL, NULL);
1690 if (!fh || fh==INVALID_HANDLE_VALUE)
1693 nbytes=GetFileSize((HANDLE)fh, NULL);
1694 // read in the bitmap file header. save the offset to bits.
1695 pbmfh = (PBITMAPFILEHEADER)LocalAlloc(LPTR, sizeof(BITMAPFILEHEADER));
1699 ReadFile(fh, (LPVOID)pbmfh, sizeof(BITMAPFILEHEADER),&bytesRead,NULL);
1700 bfOffBits=pbmfh->bfOffBits;
1702 // read in the bitmap info header and the color table right after it.
1703 pbmih = (PBITMAPINFOHEADER)LocalAlloc(LPTR, bfOffBits- sizeof(BITMAPFILEHEADER));
1706 ReadFile(fh, (LPVOID)pbmih, bfOffBits-sizeof(BITMAPFILEHEADER),&bytesRead,NULL);
1708 // finally read in the bit data.
1709 pBits = (PBYTE)LocalAlloc (LPTR, (nbytes - bfOffBits));
1712 ReadFile(fh, (LPVOID)pBits, nbytes-bfOffBits,&bytesRead,NULL);
1714 hbm=CreateDIBitmap(aHdc, pbmih, CBM_INIT, pBits,(PBITMAPINFO) pbmih, DIB_RGB_COLORS);
1716 LocalFree(LocalHandle ((LPSTR)pBits));
1717 LocalFree(LocalHandle ((LPSTR)pbmih));
1718 LocalFree(LocalHandle ((LPSTR)pbmfh));
1723 void LoadFasciaBitmap(TInt aScreen)
1725 HDC hdc=GetDC(TheWin[aScreen]);
1726 RECT windowRect = {0};
1727 windowRect.right=systemIni->iScreens[aScreen]->iXYInputWidth;
1728 windowRect.bottom=systemIni->iScreens[aScreen]->iXYInputHeight;
1729 HBITMAP screenBitmap=readBitmap(hdc, systemIni->iScreens[aScreen]->iFasciaFileName);
1730 if (screenBitmap==NULL)
1732 screenBitmap=CreateCompatibleBitmap(hdc, windowRect.right-windowRect.left, windowRect.bottom-windowRect.top);
1733 HDC hdcMem=CreateCompatibleDC(hdc);
1734 SelectObject(hdcMem, screenBitmap);
1735 PatBlt(hdcMem, 0, 0, windowRect.right-windowRect.left, windowRect.bottom-windowRect.top, BLACKNESS);
1738 __ASSERT_ALWAYS(screenBitmap!=NULL,Fault(EGuiCreateBitmap));
1739 TheScreenBitmap[aScreen]=screenBitmap;
1743 ReleaseDC(TheWin[aScreen], hdc);
1745 TBool DWinsUi::MultiTouchEnabled() const
1747 return iMultiTouchEnabled;
1750 TBool DWinsUi::GCEEnabled() const
1755 TInt DWinsUi::MultiTouchProximityStep() const
1757 return iMultiTouchProximityStep;
1760 TInt DWinsUi::MultiTouchPressureStep() const
1762 return iMultiTouchPressureStep;
1765 TBool DWinsUi::OnDigitizer(TInt aX, TInt aY) const
1767 if (!iDigitizerEnabled)
1769 switch(CurrentFlipState[0])
1771 case EEmulatorFlipRestore:
1773 aX -= iDigitizerOffsetX;
1774 aY -= iDigitizerOffsetY;
1777 case EEmulatorFlipInvert:
1779 aX -= systemIni->iScreens[0]->iScreenWidth - iDigitizerOffsetX - iDigitizerWidth;
1780 aY -= systemIni->iScreens[0]->iScreenHeight - iDigitizerOffsetY - iDigitizerHeight;
1783 case EEmulatorFlipRight:
1786 aY = aX - (systemIni->iScreens[0]->iScreenHeight - iDigitizerOffsetY - iDigitizerHeight);
1787 aX = oldY - iDigitizerOffsetX;
1790 case EEmulatorFlipLeft:
1793 aY = aX - iDigitizerOffsetY;
1794 aX = oldY - (systemIni->iScreens[0]->iScreenWidth - iDigitizerOffsetX - iDigitizerWidth);
1798 return (TUint(aX) < TUint(iDigitizerWidth) && TUint(aY) < TUint(iDigitizerHeight));
1801 LOCAL_C void addMouseEvent(TRawEvent::TType aType,TInt aXpos,TInt aYpos)
1803 // Add a mouse event.
1806 if (systemIni->OnDigitizer(aXpos, aYpos))
1809 v.Set(aType,aXpos,aYpos);
1814 LOCAL_C void addMouseEvent(TRawEvent::TType aType,TInt aXpos,TInt aYpos,TInt aZpos, TInt aPointerId=0)
1816 // Add a multitouch mouse event.
1819 if (systemIni->OnDigitizer(aXpos, aYpos))
1822 v.Set(aType,aXpos,aYpos, aZpos);
1823 v.SetPointerNumber(static_cast<const TUint8>(aPointerId));
1827 LOCAL_C void addKeyEvent(TRawEvent::TType aType,TInt aKey)
1835 LOCAL_C void SwitchConfiguration(TInt aData, TBool aSendFlipKey = ETrue)
1837 if (aData < 0 || aData >= masterIni->iSystemInis.Count())
1840 CurrentConfiguration = aData;
1841 systemIni = masterIni->iSystemInis[aData];
1843 //get the correct fascia bitmaps
1844 TInt screens=systemIni->iScreens.Count();
1846 TUint disabledWinType=ENormalResolution;
1847 for(i=0;i<screens;i++)
1849 DeleteObject(TheScreenBitmap[i]);
1850 LoadFasciaBitmap(i);
1851 if (masterIni->iBufferSet[i].iDisplayState!=ENormalResolution)
1853 disabledWinType=masterIni->iBufferSet[i].iDisplayState;
1857 //update the window title
1858 if (disabledWinType!=ENormalResolution && disabledWinType < 4) //hardwired 4 because the code below is hardwired
1859 { //string may be multi-part indexed by disable type, or it may not
1860 CHAR* firstsemi=strchr(systemIni->iWindowTitle,';');
1861 CHAR* secondsemi=NULL;
1864 secondsemi=strchr(firstsemi+1,';');
1866 if (firstsemi&&secondsemi)
1870 char* ptr[4]={0,systemIni->iWindowTitle,firstsemi+1,secondsemi+1};
1871 SetWindowTextA(TheControlWin, ptr[disabledWinType]);
1877 SetWindowTextA(TheControlWin, systemIni->iWindowTitle);
1883 SetWindowTextA(TheControlWin, systemIni->iWindowTitle);
1885 //resize and repaint the current window anyway.
1886 //the text window server doesn't respond to orientation messages
1887 for(i=0;i<screens;i++)
1889 InvalidateRect(TheWin[i], NULL, false);
1890 SendMessage(TheWin[i], WM_FLIP_MESSAGE, systemIni->iScreens[i]->iScreenRotation,0);
1893 //pass on the orientation key to the windows server
1896 if (!WinsGuiPowerHandler->iStandby)
1898 addKeyEvent(TRawEvent::EKeyDown, systemIni->iInitialFlipMsg);
1899 addKeyEvent(TRawEvent::EKeyUp, systemIni->iInitialFlipMsg);
1903 //remember the flip message so we can send it to the window server when we come out of standby
1904 SavedFlipMessage = systemIni->iInitialFlipMsg;
1909 Sets the specified screen to the given width and height, if available.
1911 The configurations are searched to find a match, taking the display state into
1912 account. If no configuration is available, the request is ignored.
1914 @param aScreenNumber the screen index
1915 @param aWidth the desired width
1916 @param aHeight the desired height
1918 void DMasterIni::SetDisplaySize(TInt aDisplayNumber, TInt aWidth, TInt aHeight)
1920 TInt displayCount = iBufferSet.Count();
1922 if (aDisplayNumber < 0 || aDisplayNumber >= displayCount)
1924 // Invalid screen number, discard.
1928 if (iBufferSet[aDisplayNumber].iDisplayState != ENormalResolution)
1930 // No (non-zero) resolutions available, discard.
1934 TInt count = iSystemInis.Count();
1936 for (index = 0; index < count; index++)
1938 DWinsUi* newIni = masterIni->iSystemInis[index];
1939 DScreenProperties* newProps = newIni->iScreens[aDisplayNumber];
1941 if (newProps->iScreenWidth == aWidth && newProps->iScreenHeight == aHeight)
1943 // Found a potential match. Check other screens match their current size.
1944 if (newIni == systemIni)
1946 // Current configuration, already in use. Nothing to do.
1951 for (display = 0; display < displayCount; display++)
1953 if (display == aDisplayNumber)
1955 // No need to check the display we are changing
1959 DScreenProperties* currentPropsN = systemIni->iScreens[display];
1960 DScreenProperties* newPropsN = newIni->iScreens[display];
1962 if (newPropsN->iScreenWidth != currentPropsN->iScreenWidth ||
1963 newPropsN->iScreenHeight != currentPropsN->iScreenHeight)
1965 // Resolution mismatch, try next configuration.
1970 if (display == displayCount)
1972 // Match found, switch to this configuration and stop. Force
1973 // rotation to the same as the current rotation.
1974 newProps->iScreenRotation = systemIni->iScreens[aDisplayNumber]->iScreenRotation;
1975 SwitchConfiguration(index);
1983 void DMasterIni::SetBufferFormat(TInt aDisplayNumber, TUint aAggregateSize, RDisplayChannel::TPixelFormat aPixelFormat)
1985 TInt displayCount = iBufferSet.Count();
1987 if (aDisplayNumber < 0 || aDisplayNumber >= displayCount)
1989 // Invalid screen number, discard.
1993 LPBITMAPV4HEADER info = &iBufferSet[aDisplayNumber].iInfo;
1995 // update the bitmap header taking in consideration the new pixel format
1996 switch (aPixelFormat)
1998 case EUidPixelFormatXRGB_4444:
1999 case EUidPixelFormatARGB_4444:
2000 info->bV4BitCount=16;
2001 info->bV4V4Compression = BI_BITFIELDS;
2002 info->bV4RedMask = 0x0F00;
2003 info->bV4GreenMask = 0x00F0;
2004 info->bV4BlueMask = 0x000F;
2006 case EUidPixelFormatRGB_565:
2007 info->bV4BitCount=16;
2008 info->bV4V4Compression = BI_BITFIELDS;
2009 info->bV4RedMask = 0xF800;
2010 info->bV4GreenMask = 0x07E0;
2011 info->bV4BlueMask = 0x001F;
2013 case EUidPixelFormatXRGB_8888: // Really 32bpp, but top 8 unused
2014 case EUidPixelFormatARGB_8888:
2015 case EUidPixelFormatARGB_8888_PRE:
2016 info->bV4BitCount=32;
2017 info->bV4V4Compression = BI_RGB;
2018 // Mask is implicit for BI_RGB compression
2021 // We got an error, it seems. Let's ignore the message
2024 iBufferSet[aDisplayNumber].iBufferFormat.iPixelFormat = aPixelFormat;
2026 // taking advantage of limiting the width and size to KMaxTInt16
2027 TInt width = aAggregateSize & 0x0000ffff;
2028 TInt height = (aAggregateSize >> 16) & 0x0000ffff;
2030 // let's deal with the new size just received
2031 iBufferSet[aDisplayNumber].iBufferFormat.iSize.iWidth = width;
2032 iBufferSet[aDisplayNumber].iBufferFormat.iSize.iHeight = height;
2034 // update the bitmap header, taking in consideration the rotation
2035 switch (CurrentFlipState[aDisplayNumber])
2037 case EEmulatorFlipRestore:
2038 case EEmulatorFlipInvert:
2039 info->bV4Width = width;
2040 info->bV4Height = -height;
2042 case EEmulatorFlipLeft:
2043 case EEmulatorFlipRight:
2044 info->bV4Width = height;
2045 info->bV4Height = -width;
2048 // finally, update the image size
2049 SetImageSize(aDisplayNumber);
2052 void DMasterIni::SetImageSize(TInt aScreenNumber)
2054 TInt displayCount = iBufferSet.Count();
2056 if (aScreenNumber >= 0 && aScreenNumber < displayCount)
2058 LPBITMAPV4HEADER info = &iBufferSet[aScreenNumber].iInfo;
2059 TInt bpp = _ALIGN_UP(info->bV4BitCount, 16); //12 & 16 --> 16 ; 24 & 32 --> 32
2060 TInt widthInBpp = info->bV4Width * bpp;
2061 //rounding to 32 bits (4 octets) and converting, then, bits to octets;
2062 TInt scanLineInBytes = _ALIGN_UP(widthInBpp, 32) >> 3;
2063 // info->bV4Height is negative or zero
2064 info->bV4SizeImage = -info->bV4Height * scanLineInBytes;
2068 LOCAL_C void NextConfiguration()
2070 TInt config = CurrentConfiguration;
2071 if (++config == masterIni->iSystemInis.Count())
2073 SwitchConfiguration(config);
2078 LOCAL_C TBool ProcessedByEmulatorKey(TInt aScanCode, HWND hWnd,TUint message,TUint wParam,TUint lParam)
2081 TBool rVal = EFalse;
2083 for (TInt i=0;i<systemIni->iControlHotKeys.Count();i++)//check key combinations
2085 if (systemIni->iControlHotKeys[i]->CheckCombinationPressed())
2087 switch (systemIni->iControlHotKeys[i]->iCommand)
2091 NextConfiguration();
2095 SwitchConfiguration(systemIni->iControlHotKeys[i]->iData);
2107 // Simulate a change of media card
2108 TInt irq = NKern::DisableAllInterrupts();
2109 if (*Wins::MediaDoorOpenPtr())
2111 *Wins::CurrentPBusDevicePtr() += 1;
2112 if (*Wins::CurrentPBusDevicePtr() == 2)
2114 *Wins::CurrentPBusDevicePtr() = -1;
2117 NKern::RestoreInterrupts(irq);
2119 // pass on to the windows system so that if
2120 // Alt-F4 is pressed the window will close
2122 DefWindowProcA(hWnd,message,wParam,lParam);
2133 LOCAL_C void MultiChildWndPointer(TUint aMessage,TInt aXpos,TInt aYpos, TInt aZ, TInt aPointerId)
2135 // Handle a multi-touch pointer event in the Symbian OS screen window
2138 TRawEvent::TType eventType=TRawEvent::ENone;
2141 if (aZ <= TheMultiTouch->iZMaxRange) //negative
2143 eventType = TRawEvent::EPointer3DOutOfRange;
2144 wsprintf((LPTSTR)buf, (LPCTSTR)TEXT("Out Of Range"));
2145 SendMessage(hwndStatus, SB_SETTEXT, aPointerId , (LPARAM)(buf));
2149 wsprintf((LPTSTR)buf, (LPCTSTR)TEXT("%d: %d,%d,%d"), aPointerId, aXpos,aYpos,aZ);
2150 SendMessage(hwndStatus, SB_SETTEXT, aPointerId , (LPARAM)(buf));
2155 eventType=TRawEvent::EPointerMove;
2158 case WM_LBUTTONDOWN:
2160 SetCapture(TheChildWin[0]);
2161 eventType = TRawEvent::EButton1Down;
2167 eventType = TRawEvent::EButton1Up;
2170 case WM_RBUTTONDOWN:
2172 eventType = TRawEvent::EButton3Down;
2177 eventType = TRawEvent::EButton3Up;
2182 eventType = TRawEvent::EPointerMove;
2190 if (!WinsGuiPowerHandler->iStandby)
2192 addMouseEvent(eventType, aXpos, aYpos, aZ, aPointerId);
2196 LOCAL_C void ChildWndPointer(TUint message,TInt aXpos,TInt aYpos)
2198 // Handle a pointer event in the Symbian OS screen window
2201 // Enable the multitouch if the cursor is inside the main client window
2202 if (DMultiTouch::iMultiTouchCreated)
2206 GetWindowInfo(TheChildWin[0], &info);
2207 POINT pt = {aXpos+(TInt)info.rcClient.left, aYpos+(TInt)info.rcClient.top};
2208 if (GetWindowRect(TheChildWin[0], &client) &&
2209 (PtInRect(&client,pt)!=NULL) && !DMultiTouch::iMultiTouchTempEnabled) // within the window
2211 if (systemIni->MultiTouchEnabled() && systemIni->GCEEnabled())
2213 if(TheMultiTouch->Register()) // Register successfully
2215 DMultiTouch::iMultiTouchTempEnabled = TRUE;
2216 //Show the status bars at the bottom of the emulator
2217 SetWindowPos(hwndStatus,0,0,0,0,0,SWP_SHOWWINDOW);
2218 SetFocus(TheWin[0]);
2219 SetCursor(LoadCursorA(NULL,MAKEINTRESOURCEA(32512)));
2224 TRawEvent::TType eventType=TRawEvent::ENone;
2228 eventType=TRawEvent::EPointerMove;
2230 case WM_LBUTTONDOWN:
2232 SetCapture(TheChildWin[0]);
2233 eventType=TRawEvent::EButton1Down;
2238 eventType=TRawEvent::EButton1Up;
2240 case WM_RBUTTONDOWN:
2241 eventType=TRawEvent::EButton3Down;
2244 eventType=TRawEvent::EButton3Up;
2246 case WM_MBUTTONDOWN:
2247 eventType=TRawEvent::EButton2Down;
2250 eventType=TRawEvent::EButton2Up;
2253 if (!WinsGuiPowerHandler->iStandby)
2255 addMouseEvent(eventType, aXpos, aYpos);
2259 LOCAL_C void FrameWndPointer(TUint message,TInt aXpos,TInt aYpos, TInt aScreenNumber, TInt aPointerId = 0)
2261 // Handle a frame wnd pointer event.
2264 static bool processingScreenOn=FALSE;
2265 TEmulCommand command = ENoCommand;
2266 TInt commandData = 0;
2267 TBool mouseEvent = ETrue;
2269 TRawEvent::TType eventType=TRawEvent::ENone;
2271 TViewport& viewport = systemIni->iScreens[aScreenNumber]->iViewport;
2272 aXpos += viewport.GetViewportOffsetX(); // make mouse-coords relative to fascia edge even if window is scrolled
2273 aYpos += viewport.GetViewportOffsetY();
2280 systemIni->TranslateMouseCoords(CurrentFlipState[0], aXpos, aYpos, systemIni->iScreens[0]->iXYInputWidth, systemIni->iScreens[0]->iXYInputHeight, newX, newY);
2282 if (aPointerId == 0)
2283 { // only system pointer changes shape
2284 if (systemIni->GetVirtualKey(command, newX, newY) >= 0)
2286 HMODULE hmodule = GetModuleHandleA("winsgui.dll");
2287 SetCursor(LoadCursorA((HINSTANCE)hmodule,MAKEINTRESOURCEA(OVERKEY))); //hand cursor
2290 SetCursor(LoadCursorA(NULL,MAKEINTRESOURCEA(32512))); //ICD_ARROW
2293 eventType=TRawEvent::EPointerMove;
2297 case WM_LBUTTONDOWN:
2299 SetCapture(TheWin[0]);
2300 //check the configuration
2303 //if the emulator screen is rotated, rotate/flip the current mouse cursor position
2304 //so it can be checked to see if it is in a key region.
2305 systemIni->TranslateMouseCoords(CurrentFlipState[0], aXpos, aYpos, systemIni->iScreens[0]->iXYInputWidth, systemIni->iScreens[0]->iXYInputHeight, newX, newY);
2306 commandData = systemIni->GetVirtualKey(command, newX, newY);
2308 if (commandData >= 0)
2310 eventType=TRawEvent::EKeyDown;
2311 mouseEvent = EFalse;
2312 systemIni->SetVirtualKey(ETrue, commandData, command);
2315 eventType=TRawEvent::EButton1Down;
2320 if (processingScreenOn)
2322 // ignore button up - button down was switching things on
2323 processingScreenOn=FALSE;
2326 if (systemIni->WasVirtualKey(commandData, command))
2328 eventType=TRawEvent::EKeyUp;
2329 mouseEvent = EFalse;
2330 systemIni->SetVirtualKey(EFalse, EStdKeyNull, ENoCommand);
2333 eventType=TRawEvent::EButton1Up;
2335 case WM_RBUTTONDOWN:
2336 eventType=TRawEvent::EButton3Down;
2339 eventType=TRawEvent::EButton3Up;
2341 case WM_MBUTTONDOWN:
2342 eventType=TRawEvent::EButton2Down;
2345 eventType=TRawEvent::EButton2Up;
2351 if (!WinsGuiPowerHandler->iStandby)
2354 mouse events are relative to the child window position
2355 and are clipped to the digitzer region in addMouseEvent
2356 so all the mouse clicks are passed on here after being translated
2357 to the child window coordinate system (under the current rotation)
2360 switch (CurrentFlipState[0])
2362 case EEmulatorFlipRestore:
2364 newX = aXpos - systemIni->iScreens[0]->iScreenOffsetX;
2365 newY = aYpos - systemIni->iScreens[0]->iScreenOffsetY;
2367 case EEmulatorFlipInvert:
2368 newX = aXpos - (systemIni->iScreens[0]->iXYInputWidth - systemIni->iScreens[0]->iScreenWidth - systemIni->iScreens[0]->iScreenOffsetX);
2369 newY = aYpos - (systemIni->iScreens[0]->iXYInputHeight - systemIni->iScreens[0]->iScreenHeight - systemIni->iScreens[0]->iScreenOffsetY);
2371 case EEmulatorFlipLeft:
2372 newX = aXpos - systemIni->iScreens[0]->iScreenOffsetY;
2373 newY = aYpos - (systemIni->iScreens[0]->iXYInputWidth - systemIni->iScreens[0]->iScreenWidth - systemIni->iScreens[0]->iScreenOffsetX);
2375 case EEmulatorFlipRight:
2376 newX = aXpos - (systemIni->iScreens[0]->iXYInputHeight - systemIni->iScreens[0]->iScreenHeight - systemIni->iScreens[0]->iScreenOffsetY);
2377 newY = aYpos - systemIni->iScreens[0]->iScreenOffsetX;
2380 addMouseEvent(eventType, newX, newY);
2383 else if ((((message == WM_LBUTTONDOWN && command == EKey) && !ProcessedByEmulatorKey((TUint8)commandData,0,0,0,0)))
2384 || (message == WM_LBUTTONUP))
2389 if (!WinsGuiPowerHandler->iStandby)
2390 addKeyEvent(eventType, (TUint8)commandData);
2394 NextConfiguration();
2398 SwitchConfiguration(commandData);
2404 LOCAL_C TInt ScreenFromHWND(HWND aHwnd,HWND* pWin)
2406 TInt screens=systemIni->iScreens.Count();
2408 for(TInt i=0;i<screens;i++)
2418 void MultiTouchWndPointer(TUint message,TInt aXpos,TInt aYpos, TInt aZ, TInt aPointerId)
2421 info.cbSize = sizeof(WINDOWINFO);
2422 if (GetWindowInfo(TheWin[0], &info))
2424 POINT pt = {aXpos,aYpos};
2425 if (PtInRect(&info.rcWindow,pt))
2428 if (GetWindowRect(TheChildWin[0], &client) && PtInRect(&client,pt)) // within the window
2430 MultiChildWndPointer(message, aXpos-client.left, aYpos-client.top, aZ, aPointerId);
2434 // Disable the multitouch if the cursor is outside the application window
2435 if (DMultiTouch::iMultiTouchTempEnabled) // within the window
2437 DMultiTouch::iMultiTouchTempEnabled = FALSE;
2438 if(TheMultiTouch->UnRegister())
2440 SetWindowPos(hwndStatus,0,0,0,0,0,SWP_HIDEWINDOW);
2443 FrameWndPointer(message, aXpos-info.rcClient.left, aYpos-info.rcClient.top, 0, aPointerId);
2449 LOCAL_C DScreenProperties* ScreenPropsFromHWND(HWND aHwnd, HWND* pWin)
2451 TInt screenNumber = ScreenFromHWND(aHwnd, pWin);
2453 if(screenNumber >=0)
2455 return systemIni->iScreens[screenNumber];
2462 TInt APIENTRY childWinProc(HWND hWnd,TUint message,TUint wParam,TUint lParam)
2464 // The child window function.
2467 TInt screenNumber = 0;
2471 case WM_FLIP_MESSAGE: // pass the flip message onto the parent window
2473 screenNumber =ScreenFromHWND(hWnd,TheChildWin);
2474 if(TUint(screenNumber) < TUint(systemIni->iScreens.Count()))
2475 PostMessageA(TheWin[screenNumber],WM_FLIP_MESSAGE,wParam,NULL);
2478 case WM_LBUTTONDOWN:
2481 case WM_RBUTTONDOWN:
2483 case WM_MBUTTONDOWN:
2486 if (DMultiTouch::iMultiTouchTempEnabled)
2488 DMultiTouch::iMultiTouchTempEnabled = FALSE;
2490 screenNumber=ScreenFromHWND(hWnd,TheChildWin);
2493 ChildWndPointer(message,(TInt16)(lParam&0xFFFF),(TInt16)((lParam>>16)&0xFFFF));
2498 if (!PaintWindowFromBuffer(hWnd))
2500 // Original behaviour
2501 ValidateRect(hWnd,NULL);
2502 v.Set(TRawEvent::ERedraw);
2511 Fault(EGuiChildWinProc);
2519 case WM_SYSDEADCHAR:
2522 case WMU_SET_DISPLAY_BUFFER:
2523 screenNumber = ScreenFromHWND(hWnd, TheChildWin);
2524 if (TUint(screenNumber) < TUint(systemIni->iScreens.Count()))
2526 masterIni->iBufferSet[screenNumber].iDisplayBuffer = (LPVOID)lParam;
2529 case WMU_SET_DISPLAY_SIZE:
2530 screenNumber = ScreenFromHWND(hWnd, TheChildWin);
2531 masterIni->SetDisplaySize(screenNumber, wParam, lParam);
2534 case WMU_SET_BUFFER_FORMAT:
2535 screenNumber = ScreenFromHWND(hWnd, TheChildWin);
2536 masterIni->SetBufferFormat(screenNumber, wParam, (RDisplayChannel::TPixelFormat) lParam);
2540 return(DefWindowProcA(hWnd,message,wParam,lParam));
2546 LOCAL_C TBool PaintWindowFromBuffer(HWND hWnd)
2548 TInt screenNumber = ScreenFromHWND(hWnd,TheChildWin);
2549 if (TUint(screenNumber) >= TUint(masterIni->iBufferSet.Count()))
2554 LPVOID displayBuffer = masterIni->iBufferSet[screenNumber].iDisplayBuffer;
2560 TInt frameOffset = masterIni->iBufferSet[screenNumber].iScreenBuffer.iDisplayBufferOffset;
2561 displayBuffer=LPVOID(frameOffset+(char*)displayBuffer);
2564 BeginPaint(hWnd, &ps);
2566 // Paint directly from the buffer to the window
2567 LPBITMAPINFO info = (LPBITMAPINFO)&masterIni->iBufferSet[screenNumber].iInfo;
2568 WORD width = (WORD)info->bmiHeader.biWidth;
2569 WORD height = (WORD)-info->bmiHeader.biHeight; // stored -ve in info
2570 SetDIBitsToDevice(ps.hdc,
2572 width, height, // Src W, H
2574 0, // Src offset to first line
2575 height, // Src lines available
2576 displayBuffer, // Src pointer to pixels
2580 EndPaint(hWnd, &ps);
2586 LOCAL_C void CalcTextPos(TInt aScreen, TInt& aX, TInt& aY)
2588 switch (CurrentFlipState[aScreen])
2590 case EEmulatorFlipInvert:
2591 aX = systemIni->iScreens[aScreen]->iXYInputWidth-(systemIni->iScreens[aScreen]->iScreenOffsetX+systemIni->iScreens[aScreen]->iScreenWidth);
2592 aY = systemIni->iScreens[aScreen]->iXYInputHeight-(systemIni->iScreens[aScreen]->iScreenOffsetY+systemIni->iScreens[aScreen]->iScreenHeight);
2594 case EEmulatorFlipLeft:
2595 aX = systemIni->iScreens[aScreen]->iScreenOffsetY;
2596 aY = systemIni->iScreens[aScreen]->iXYInputWidth-(systemIni->iScreens[aScreen]->iScreenOffsetX+systemIni->iScreens[aScreen]->iScreenWidth);
2598 case EEmulatorFlipRight:
2599 aX = systemIni->iScreens[aScreen]->iXYInputHeight-(systemIni->iScreens[aScreen]->iScreenOffsetY+systemIni->iScreens[aScreen]->iScreenHeight);
2600 aY = systemIni->iScreens[aScreen]->iScreenOffsetX;
2602 case EEmulatorFlipRestore:
2604 aX = systemIni->iScreens[aScreen]->iScreenOffsetX;
2605 aY = systemIni->iScreens[aScreen]->iScreenOffsetY;
2608 //subtract viewport offset here
2609 aX -= systemIni->iScreens[aScreen]->iViewport.GetViewportOffsetX();
2610 aY -= systemIni->iScreens[aScreen]->iViewport.GetViewportOffsetY();
2613 TInt APIENTRY ctrlwinProc(HWND hWnd,TUint message,TUint wParam,TUint lParam)
2615 // The control window function
2626 NextConfiguration();
2632 if (wParam == SC_RESTORE)
2634 for(TInt ix=0;ix<systemIni->iScreens.Count();ix++)
2636 SendMessage(TheWin[ix],message,wParam,lParam);
2638 if (wParam == SC_MINIMIZE)
2642 return(DefWindowProcA(hWnd,message,wParam,lParam));
2644 case WM_CLOSE: // tell all emulator screen windows to close
2646 for(TInt i=0;i<systemIni->iScreens.Count();i++)
2648 DestroyWindow(TheWin[i]);
2650 DestroyWindow(hWnd);
2655 // save the main window position information
2657 hSysIni = CreateFileA(systemIni->iSysIniFileName, GENERIC_WRITE, 0, 0, CREATE_ALWAYS, 0, 0);
2658 DScreenProperties* screenProps;
2659 if (hSysIni != INVALID_HANDLE_VALUE)
2662 //write an identifier into file so that program can avoid loading old version
2663 WriteFile(hSysIni, &KDatFileVersion, sizeof(TInt), &numWritten, 0);
2665 //record current configuration at start of file.
2666 WriteFile(hSysIni, &CurrentConfiguration, sizeof(TInt), &numWritten, 0);
2668 //Write out the state for each window.
2669 for(TInt i=0;i<systemIni->iScreens.Count();i++)
2671 screenProps= systemIni->iScreens[i];
2673 TWindowState winState= screenProps->GetWindowState();
2674 WriteFile(hSysIni, &winState, sizeof(TWindowState), &numWritten, 0);
2679 CloseHandle(hSysIni);
2681 PostQuitMessage(KErrNone);
2686 if (!DMultiTouch::iMultiTouchTempEnabled)
2688 for(TInt ix=0;ix<systemIni->iScreens.Count();ix++)
2690 DMultiTouch::iMultiTouchTempEnabled = TRUE;
2692 SendMessage(TheWin[ix],message,wParam,lParam);
2695 else if (systemIni->MultiTouchEnabled() && DMultiTouch::iMultiTouchSupported && systemIni->GCEEnabled())
2697 TheMultiTouch->OnWmInput(hWnd, message, wParam, lParam,TheChildWin[0]);
2701 Fault(EGuiInvalidMultiTouch);
2706 return(DefWindowProcA(hWnd,message,wParam,lParam));
2711 TInt APIENTRY winProc(HWND hWnd,TUint message,TUint wParam,TUint lParam)
2713 // The border window function.
2721 case WM_GETMINMAXINFO:
2723 DScreenProperties* screenProps = ScreenPropsFromHWND(hWnd, TheWin);
2724 if(screenProps == NULL)
2726 return DefWindowProcA(hWnd, message, wParam, lParam);
2729 MINMAXINFO* minMaxInfo = reinterpret_cast<MINMAXINFO*>(lParam);
2730 minMaxInfo->ptMaxTrackSize.x = screenProps->iViewport.GetMaxWindowWidth();
2731 minMaxInfo->ptMaxTrackSize.y = screenProps->iViewport.GetMaxWindowHeight();
2733 minMaxInfo->ptMaxSize.x = minMaxInfo->ptMaxTrackSize.x;
2734 minMaxInfo->ptMaxSize.y = minMaxInfo->ptMaxTrackSize.y;
2735 DefWindowProcA(hWnd, message, wParam, lParam);
2744 DScreenProperties* screenProps = ScreenPropsFromHWND(hWnd, TheWin);
2745 if(screenProps == NULL)
2747 return DefWindowProcA(hWnd, message, wParam, lParam);
2749 TViewport& viewport = screenProps->iViewport;
2750 //update size of viewport
2751 viewport.SetViewportWidth(LOWORD(lParam));
2752 viewport.SetViewportHeight(HIWORD(lParam));
2755 //If resize goes beyond boundary of emulator then scroll to compensate
2756 TInt ox = viewport.GetViewportOffsetX();
2757 TInt xs = ox + LOWORD(lParam) - viewport.GetMaxWidth();
2760 viewport.ScrollToX(ox-xs, hWnd);
2763 TInt oy = viewport.GetViewportOffsetY();
2764 TInt ys = oy + HIWORD(lParam) - viewport.GetMaxHeight();
2767 viewport.ScrollToY(oy-ys, hWnd);
2770 //Adjust ranges of scroll bars
2771 viewport.UpdateScrollBarH(hWnd);
2772 viewport.UpdateScrollBarV(hWnd);
2780 DScreenProperties* screenProps = ScreenPropsFromHWND(hWnd, TheWin);
2781 if(screenProps == NULL)
2783 return DefWindowProcA(hWnd, message, wParam, lParam);
2785 TViewport& viewport = screenProps->iViewport;
2787 switch (LOWORD(wParam))
2791 viewport.ScrollToX(HIWORD(wParam),hWnd);
2796 viewport.ScrollToX(viewport.GetViewportOffsetX() - viewport.GetViewportWidth(), hWnd );
2801 viewport.ScrollToX(viewport.GetViewportOffsetX() + viewport.GetViewportWidth() , hWnd);
2806 viewport.ScrollToX(viewport.GetViewportOffsetX() - 1, hWnd);
2811 viewport.ScrollToX(viewport.GetViewportOffsetX() + 1, hWnd);
2823 DScreenProperties* screenProps = ScreenPropsFromHWND(hWnd, TheWin);
2824 if(screenProps == NULL)
2826 return DefWindowProcA(hWnd, message, wParam, lParam);
2828 TViewport& viewport = screenProps->iViewport;
2831 switch (LOWORD(wParam))
2835 viewport.ScrollToY(HIWORD(wParam), hWnd);
2840 viewport.ScrollToY(viewport.GetViewportOffsetY() - viewport.GetViewportHeight() , hWnd);
2845 viewport.ScrollToY(viewport.GetViewportOffsetY() + viewport.GetViewportHeight(), hWnd );
2850 viewport.ScrollToY(viewport.GetViewportOffsetY() - 1, hWnd);
2855 viewport.ScrollToY(viewport.GetViewportOffsetY() + 1, hWnd);
2866 case WM_FLIP_MESSAGE:
2868 DScreenProperties* screenProps = ScreenPropsFromHWND(hWnd, TheWin);
2869 if(screenProps == NULL)
2871 return DefWindowProcA(hWnd, message, wParam, lParam);
2875 TViewport& viewport = screenProps->iViewport;
2876 RECT windowRect={0,0,0,0};
2877 GetClientRect(hWnd, &windowRect);
2879 TInt screenNumber=ScreenFromHWND(hWnd,TheWin);
2880 if(TUint(screenNumber) >= TUint(systemIni->iScreens.Count()))
2882 PBITMAPV4HEADER info = &masterIni->iBufferSet[screenNumber].iInfo;
2883 CurrentFlipState[screenNumber]=(TEmulatorFlip)wParam;
2884 TBufferSet* bufferSet = &masterIni->iBufferSet[screenNumber];
2885 switch (CurrentFlipState[screenNumber])
2887 case EEmulatorFlipRestore:
2888 case EEmulatorFlipInvert:
2889 windowRect.right=systemIni->iScreens[screenNumber]->iXYInputWidth;
2890 windowRect.bottom=systemIni->iScreens[screenNumber]->iXYInputHeight;
2891 info->bV4Width = bufferSet->iBufferFormat.iSize.iWidth;
2892 info->bV4Height = -bufferSet->iBufferFormat.iSize.iHeight;
2894 case EEmulatorFlipLeft:
2895 case EEmulatorFlipRight:
2896 windowRect.right=systemIni->iScreens[screenNumber]->iXYInputHeight;
2897 windowRect.bottom=systemIni->iScreens[screenNumber]->iXYInputWidth;
2898 info->bV4Width = bufferSet->iBufferFormat.iSize.iHeight;
2899 info->bV4Height = -bufferSet->iBufferFormat.iSize.iWidth;
2902 AdjustWindowRect(&windowRect,KWinStyle,FALSE);
2905 viewport.ScrollToX(0, hWnd);
2906 viewport.ScrollToY(0, hWnd);
2909 screenProps->iScreenRotation = (TEmulatorFlip)wParam;
2912 RECT currentWindowRect;
2913 GetWindowRect(hWnd,¤tWindowRect);
2914 InvalidateRect(hWnd,NULL,FALSE);
2916 TheWin[screenNumber],
2917 max(currentWindowRect.left,0), // so the window doesn't disappear off the screen
2918 max(currentWindowRect.top,0),
2919 windowRect.right-windowRect.left,
2920 windowRect.bottom-windowRect.top,
2923 // move the child window
2924 screenProps->iViewport.UpdateChildPos(hWnd);
2926 viewport.UpdateScrollBarH(hWnd);
2927 viewport.UpdateScrollBarV(hWnd);
2929 InvalidateRect(hWnd,NULL,TRUE);
2936 if (!(HIWORD(lParam)&KF_REPEAT))
2940 TUint scanCode=DWinsKeyboard::ScanCodeToStandardKey(HIWORD(lParam));
2941 TUint newScanCode = systemIni->iKeyboard.ScanCodeToRemappedKey(HIWORD(lParam));
2942 MSG msg={hWnd,message,wParam,lParam,GetMessageTime(),GetMessagePos()};
2943 TranslateMessage(&msg);
2945 // look in the message queue to get character associated with keypress
2946 // so long as the control, shift and alt keys aren't depressed
2947 if (!(HIBYTE(GetKeyState(VK_CONTROL)) && HIBYTE(GetKeyState(VK_MENU)) && HIBYTE(GetKeyState(VK_SHIFT))))
2948 if (PeekMessageA(&msg,hWnd,WM_CHAR,WM_CHAR,PM_NOREMOVE) &&
2949 scanCode == newScanCode) //no remapping
2950 charCode=msg.wParam;
2951 // Pass the character as the HIWORD of the Epoc scan code
2953 scanCode = newScanCode;
2954 v.Set(TRawEvent::EKeyDown,(charCode<<16)|scanCode);
2955 if (!ProcessedByEmulatorKey(scanCode,hWnd,message,wParam,lParam))
2962 case WM_EMUL_POWER_ON:
2964 TInt screenNumber=ScreenFromHWND(hWnd,TheWin);
2965 if(TUint(screenNumber) >= TUint(systemIni->iScreens.Count()))
2967 // HWND win = systemIni->iSecureDisplay ? TheSecureChildWin : TheChildWin;
2968 HWND win = TheChildWin[screenNumber];
2971 ShowWindow(win, SW_HIDE);
2972 ShowWindow(win, SW_SHOWNORMAL);
2973 if (SavedFlipMessage)
2975 addKeyEvent(TRawEvent::EKeyDown, SavedFlipMessage);
2976 addKeyEvent(TRawEvent::EKeyUp, SavedFlipMessage);
2977 SavedFlipMessage = 0;
2982 ShowWindow(win, SW_SHOWNORMAL);
2983 ShowWindow(win, SW_HIDE);
2990 //get the key code, this will pick up if it has been remapped or not.
2991 TUint scanCode = systemIni->iKeyboard.ScanCodeToRemappedKey(HIWORD(lParam));
2993 * We could do this to support generation of special characters using Alt+KeyPadNum
2994 * combinations, but we would need to find a way to suppress the generation of
2995 * home/end scancodes etc., so leave it for the moment.
2996 MSG msg={hWnd,message,wParam,lParam,GetMessageTime(),GetMessagePos()};
2997 TranslateMessage(&msg);
2999 // look in the message queue to get character associated with keypress
3000 if (PeekMessageU()(&msg,hWnd,WM_CHAR,WM_CHAR,PM_NOREMOVE))
3001 charCode=msg.wParam;
3002 // Pass the character as the HIWORD of the Epoc scan code
3003 v.Set(TRawEvent::EKeyUp,(charCode<<16)|scanCode);
3005 v.Set(TRawEvent::EKeyUp,scanCode);
3010 case WM_LBUTTONDOWN:
3012 case WM_RBUTTONDOWN:
3014 case WM_MBUTTONDOWN:
3017 //only handle mouse clicks on screen 0
3018 TInt xpos=((TInt16)(lParam&0xffff));
3019 TInt ypos = (TInt16)((lParam>>16)&0xFFFF);
3020 if (DMultiTouch::iMultiTouchTempEnabled)
3022 MultiChildWndPointer(message,xpos,ypos,0,0);
3023 DMultiTouch::iMultiTouchTempEnabled = FALSE;
3027 TInt screenNumber=ScreenFromHWND(hWnd,TheWin);
3030 FrameWndPointer(message,xpos,ypos,screenNumber);
3036 DScreenProperties* screenProps = ScreenPropsFromHWND(hWnd, TheWin);
3037 if(screenProps == NULL)
3039 return DefWindowProcA(hWnd, message, wParam, lParam);
3041 TViewport& viewport = screenProps->iViewport;
3042 TInt screenNumber=ScreenFromHWND(hWnd,TheWin);
3046 BeginPaint(hWnd,&p);
3049 hdcBits=CreateCompatibleDC(p.hdc);
3050 GetObjectA(TheScreenBitmap[screenNumber],sizeof(BITMAP),&bm);
3051 SelectObject(hdcBits,TheScreenBitmap[screenNumber]);
3054 GetClientRect(TheWin[screenNumber],&windowRect);
3056 viewport.SetViewportHeight(windowRect.bottom);
3057 viewport.SetViewportWidth(windowRect.right);
3060 switch (CurrentFlipState[screenNumber])
3062 case EEmulatorFlipRestore:
3064 BitBlt(p.hdc,0,0,windowRect.right,windowRect.bottom,hdcBits,
3065 viewport.GetViewportOffsetX(),viewport.GetViewportOffsetY(),SRCCOPY);
3068 case EEmulatorFlipInvert:
3070 TInt sourceX = screenProps->iXYInputWidth - viewport.GetViewportWidth() - viewport.GetViewportOffsetX();
3073 TInt sourceY = screenProps->iXYInputHeight - viewport.GetViewportHeight() - viewport.GetViewportOffsetY();
3076 TInt sourceWidth = viewport.GetMaxWidth()-sourceX - viewport.GetViewportOffsetX();
3077 TInt sourceHeight = viewport.GetMaxHeight()-sourceY - viewport.GetViewportOffsetY();
3079 //when inverted it is necessary to translate the image by 1 pixel up and to the left,
3080 //to avoid a glitch when scrolling using ScrollWindowEx()
3081 POINT arrayPoints[3]={
3082 {sourceWidth-1,sourceHeight-1},
3083 {-1,sourceHeight-1},
3086 PlgBlt(p.hdc,arrayPoints,hdcBits,sourceX,sourceY,sourceWidth,sourceHeight,NULL,NULL,NULL);
3089 case EEmulatorFlipLeft:
3091 TInt offsetX = screenProps->iXYInputWidth- viewport.GetViewportHeight() - viewport.GetViewportOffsetY();
3092 TInt offsetY = viewport.GetViewportOffsetX();
3094 POINT arrayPoints[3]={{0,windowRect.bottom},{0,0},{windowRect.right,windowRect.bottom}};
3095 PlgBlt(p.hdc,arrayPoints,hdcBits,offsetX,offsetY,viewport.GetViewportHeight(),viewport.GetViewportWidth(),NULL,NULL,NULL);
3098 case EEmulatorFlipRight:
3100 TInt offsetX = viewport.GetViewportOffsetY();
3101 TInt offsetY = screenProps->iXYInputHeight - viewport.GetViewportWidth() - viewport.GetViewportOffsetX();
3103 POINT arrayPoints[3]={{windowRect.right,0},{windowRect.right,windowRect.bottom},{0,0}};
3104 PlgBlt(p.hdc,arrayPoints,hdcBits,offsetX,offsetY,viewport.GetViewportHeight(),viewport.GetViewportWidth(),NULL,NULL,NULL);
3111 if (WinsGuiPowerHandler->iStandby)
3114 CalcTextPos(screenNumber, x, y);
3115 TextOutA(p.hdc, x, y, "Standby", 7);
3117 else if (systemIni->iScreens[screenNumber]->iScreenOff)
3120 CalcTextPos(screenNumber, x, y);
3121 TextOutA(p.hdc, x, y, "Screen Off", 10);
3127 //Added so that change in modifier keys can be detected without sending
3128 //EActive/EInActive to wserv as it results in switching the timers
3129 if((wParam & 0xffff)!= WA_INACTIVE)
3135 case WM_SYSDEADCHAR:
3137 case WM_CLOSE: //pass on message to control window, it will then destroy all e,ulator windows
3138 SendMessage(TheControlWin,WM_CLOSE, NULL, NULL);
3142 DScreenProperties* screenProps = ScreenPropsFromHWND(hWnd, TheWin);
3143 if(screenProps == NULL)
3145 return DefWindowProcA(hWnd, message, wParam, lParam);
3148 // save window's position information
3149 screenProps->iWinPlace.length = sizeof(WINDOWPLACEMENT);
3150 GetWindowPlacement(hWnd, &screenProps->iWinPlace);
3156 if (systemIni->MultiTouchEnabled() && DMultiTouch::iMultiTouchSupported && systemIni->GCEEnabled())
3158 TInt screenNumber=ScreenFromHWND(hWnd,TheWin);
3161 TheMultiTouch->OnWmInput(hWnd, message, wParam, lParam,TheChildWin[screenNumber]);
3166 Fault(EGuiInvalidMultiTouch);
3171 return(DefWindowProcA(hWnd,message,wParam,lParam));
3177 void SetStatusBarFont(HWND& aStatusBar)
3179 int statwidths[] = {100,200,300,400,500,600,700,800};
3180 SendMessage(aStatusBar, SB_SETPARTS, sizeof(statwidths)/sizeof(int), (LPARAM)statwidths);
3181 HFONT hOrigFont = (HFONT) SendMessage(aStatusBar, WM_GETFONT, 0, 0);
3182 SetProp(aStatusBar, TEXT("PROP_ORIGINAL_FONT"), (HANDLE) hOrigFont);
3184 GetObject(hOrigFont, sizeof(lf), &lf);
3185 lf.lfHeight = (long)(lf.lfHeight / 1.5);
3186 lf.lfWeight = FW_NORMAL;
3187 HFONT hFont = CreateFontIndirect(&lf);
3188 SetProp(aStatusBar, TEXT("PROP_ITALIC_FONT"), (HANDLE) hFont);
3189 hFont = (HFONT) GetProp(hwndStatus, TEXT("PROP_ITALIC_FONT"));
3190 SendMessage(aStatusBar, WM_SETFONT, (WPARAM) hFont, FALSE);
3193 DWORD WINAPI KernelWindowThread(LPVOID aArg)
3195 // The kernel window thread.
3198 HMODULE hmodule = GetModuleHandleA("winsgui.dll");
3199 __ASSERT_ALWAYS(hmodule!=NULL,Fault(EGuiGetModuleHandle));
3202 memclr(&w, sizeof(WNDCLASSA));
3203 w.style=CS_OWNDC|CS_VREDRAW|CS_HREDRAW;
3204 w.lpfnWndProc=(WNDPROC)ctrlwinProc;
3205 w.hInstance=(HINSTANCE)aArg;
3206 w.hIcon=LoadIconA((HINSTANCE)hmodule,MAKEINTRESOURCEA(EPOC_ICON));
3207 w.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);
3208 w.lpszClassName="E32KernelControlWindow";
3210 ATOM a=RegisterClassA(&w);
3211 __ASSERT_ALWAYS(a!=0,Fault(EGuiRegisterWindow));
3213 RECT ctlrwindowRect={0,0,270,0};
3214 AdjustWindowRect(&ctlrwindowRect,KControlWinStyle,FALSE);
3215 TInt ctrlwindowWidth=ctlrwindowRect.right-ctlrwindowRect.left;
3216 TInt ctrlwindowHeight=ctlrwindowRect.bottom-ctlrwindowRect.top;
3218 TheControlWin=CreateWindowA(
3219 "E32KernelControlWindow",
3220 systemIni->iWindowTitle,
3221 KInvisibleControlWinStyle,
3231 __ASSERT_ALWAYS(TheControlWin!=NULL,Fault(EGuiKernelWindowCreate));
3233 memclr(&w, sizeof(WNDCLASSA));
3235 w.lpfnWndProc=(WNDPROC)winProc;
3236 w.hInstance=(HINSTANCE)aArg;
3237 w.hIcon=LoadIconA((HINSTANCE)hmodule,MAKEINTRESOURCEA(EPOC_ICON));
3238 w.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);
3239 w.lpszClassName="E32KernelWindow";
3241 a=RegisterClassA(&w);
3242 __ASSERT_ALWAYS(a!=0,Fault(EGuiRegisterWindow));
3244 memclr(&w, sizeof(WNDCLASSA));
3246 w.lpfnWndProc=(WNDPROC)childWinProc;
3247 w.hInstance=(HINSTANCE)aArg;
3248 w.hCursor=LoadCursorA(NULL,MAKEINTRESOURCEA(32512)); //ICD_ARROW
3249 w.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);
3250 w.lpszMenuName=NULL;
3251 w.lpszClassName="E32KernelChildWindow";
3252 a=RegisterClassA(&w);
3253 __ASSERT_ALWAYS(a!=0,Fault(EGuiRegisterChildWindow));
3255 if (masterIni && masterIni->iSystemInis.Count() > 1)
3257 //add Configuration Items to the system menu if there's > 1 config
3258 HMENU hMenu = GetSystemMenu(TheControlWin, FALSE);
3259 InsertMenu(hMenu,5, MF_BYPOSITION|MF_SEPARATOR,0,NULL);
3260 InsertMenuA(hMenu,6, MF_BYPOSITION|MF_STRING, 1, "Next Config...");
3263 ShowWindow(TheControlWin,SW_SHOWDEFAULT);
3264 UpdateWindow(TheControlWin);
3266 //Create frame windows and child windows
3267 for(TInt screen=0;screen<systemIni->iScreens.Count();screen++)
3270 RECT windowRect={0,0,systemIni->iScreens[screen]->iXYInputWidth,systemIni->iScreens[screen]->iXYInputHeight};
3271 AdjustWindowRect(&windowRect,KWinStyle,FALSE);
3272 TInt windowWidth=windowRect.right-windowRect.left;
3273 TInt windowHeight=windowRect.bottom-windowRect.top;
3276 wsprintfA(title, "Screen %d", screen);
3278 TheWin[screen]=CreateWindowA(
3291 __ASSERT_ALWAYS(TheWin[screen]!=NULL,Fault(EGuiKernelWindowCreate));
3293 LoadFasciaBitmap(screen);
3295 TheChildWin[screen]=CreateWindowA(
3296 "E32KernelChildWindow",
3298 WS_CHILDWINDOW|WS_VISIBLE|WS_CLIPCHILDREN|WS_CLIPSIBLINGS,
3299 systemIni->iScreens[screen]->iScreenOffsetX,
3300 systemIni->iScreens[screen]->iScreenOffsetY,
3301 systemIni->iScreens[screen]->iScreenWidth,
3302 systemIni->iScreens[screen]->iScreenHeight,
3308 __ASSERT_ALWAYS(TheChildWin[screen]!=NULL,Fault(EGuiKernelChildWindowCreate));
3310 // Create status bars
3311 if (systemIni->MultiTouchEnabled() && systemIni->GCEEnabled())
3313 HMODULE hmodComCtl = LoadLibrary(TEXT("comctl32.dll"));
3314 typedef int (WINAPI* FNINITCC)();
3315 FNINITCC pfnInitCommonControls = GetProcAddress(hmodComCtl, "InitCommonControls");
3316 pfnInitCommonControls();
3317 hwndStatus = CreateWindowExA(0, STATUSCLASSNAMEA, NULL,
3318 WS_CHILD | WS_VISIBLE | CCS_BOTTOM ,
3320 TheWin[0], NULL, GetModuleHandle(NULL), NULL);
3321 SetStatusBarFont(hwndStatus);
3322 SetWindowPos(hwndStatus,NULL, 0,0,0,0,SWP_HIDEWINDOW);
3326 //Restore window data from ini file if it exists.
3327 HANDLE hSysIni = CreateFileA(systemIni->iSysIniFileName, GENERIC_READ, 0, 0, OPEN_EXISTING, 0, 0);
3328 TBool success=(hSysIni != INVALID_HANDLE_VALUE) ? ETrue : EFalse;
3334 ReadFile(hSysIni, &fileVersion, sizeof(TInt), &numRead, 0);
3337 //Check we are using a dat file created by this version of the program.
3338 if(success && (fileVersion==KDatFileVersion) )
3341 TInt savedConfiguration=0; //set this to default configuration
3343 if(ReadFile(hSysIni, &savedConfiguration, sizeof(TInt), &numRead, 0) && (numRead>0) )
3345 //Don't restore the saved configuration, see INC114502.
3346 //This could be reenabled in future as an optional operation
3347 //dependent on an entry in the epoc.ini file.
3349 //SwitchConfiguration(savedConfiguration);
3352 //restore each window to saved state
3353 for(TInt screen=0;screen<systemIni->iScreens.Count();screen++)
3356 // If the .ini file was opened, get the saved settings for the windows position the last time
3357 // this emulator was run, if any, and move the window accordingly.
3359 TWindowState savedState;
3361 TBool stateLoaded = ReadFile(hSysIni, &savedState, sizeof(TWindowState), &numRead, 0) && (numRead>0);
3365 //only allow window to be restored to
3366 //maximized or normal mode,
3367 //this prevents it being restored in minimized mode
3369 if(savedState.iWinPlace.showCmd != SW_MAXIMIZE)
3370 savedState.iWinPlace.showCmd= SW_NORMAL;
3372 //if starting in same configuration and/or rotation as last time emulator was run
3373 //it makes sense to restore scroll offset, window position,
3374 //and dimensions, if not, only restore position and window (ie. maximized/normal) state.
3375 if(savedConfiguration == CurrentConfiguration &&
3376 savedState.iFlipstate == CurrentFlipState[screen])
3378 //Restore window placement
3379 SetWindowPlacement(TheWin[screen], &savedState.iWinPlace);
3381 TViewport& viewport = systemIni->iScreens[screen]->iViewport;
3383 viewport.ScrollToX(savedState.iXoffset, TheWin[screen]);
3384 viewport.ScrollToY(savedState.iYoffset, TheWin[screen]);
3390 GetWindowRect(TheWin[screen], &oldRect);
3391 //save default window dimensions
3392 TInt width=oldRect.right-oldRect.left;
3393 TInt height=oldRect.bottom - oldRect.top;
3395 //restore position and window state from file
3396 SetWindowPlacement(TheWin[screen], &savedState.iWinPlace);
3399 GetWindowRect(TheWin[screen], ¤tRect);
3400 //keep default size.
3401 MoveWindow(TheWin[screen],currentRect.left, currentRect.top, width, height, TRUE);
3406 // Check that enough of the recorded window position is visible on the screen
3408 TBool enoughVisible = false;
3410 // vague values for ensuring we have enough of the window title bar to grab
3411 // if the window is partly off screen
3412 const TInt KTitleBarGrabX=80;
3413 const TInt KTitleBarGrabY=50;
3415 //inspect dimensions of the window to be restored.
3417 GetWindowRect(TheWin[screen], &savedRect);
3419 SystemMonitors monitors;
3421 if (monitors.Count() == 1) /* Original algorithm */
3423 RECT rcIntersect, rcScreen;
3425 SetRect(&rcScreen, KTitleBarGrabX, savedRect.bottom-savedRect.top,
3426 GetSystemMetrics(SM_CXSCREEN)-KTitleBarGrabX, GetSystemMetrics(SM_CYSCREEN)-KTitleBarGrabY);
3428 enoughVisible = IntersectRect(&rcIntersect, &savedRect, &rcScreen);
3430 else /* > 1 monitor; do it differently */
3432 RECT cornerBox1, cornerBox2;
3434 // The top-left corner box
3435 SetRect(&cornerBox1, savedRect.left, savedRect.top,
3436 savedRect.left + KTitleBarGrabX, savedRect.top + KTitleBarGrabY);
3438 // The top-right corner box
3439 SetRect(&cornerBox2, savedRect.right - KTitleBarGrabX, savedRect.top,
3440 savedRect.right, savedRect.top + KTitleBarGrabY);
3442 // Require one of these rectangles to be all on one monitor
3443 enoughVisible = monitors.RectAllOnOne(cornerBox1) || monitors.RectAllOnOne(cornerBox2);
3448 SetWindowPos(TheWin[screen], HWND_TOP, 0,0,0,0, SWP_NOSIZE);
3452 else //if there was no stored info for this screen
3454 ShowWindow(TheWin[screen],SW_MAXIMIZE);
3460 //use default configuration and make windows visible
3461 SwitchConfiguration(CurrentConfiguration);
3462 for(TInt screen=0;screen<systemIni->iScreens.Count();screen++)
3464 ShowWindow(TheWin[screen],SW_MAXIMIZE);
3465 UpdateWindow(TheWin[screen]);
3469 //close file if it was opened
3472 CloseHandle(hSysIni);
3476 if (systemIni->iInitialFlipMsg != 0)
3478 addKeyEvent(TRawEvent::EKeyDown,systemIni->iInitialFlipMsg);
3479 addKeyEvent(TRawEvent::EKeyUp,systemIni->iInitialFlipMsg);
3482 SetFocus(TheWin[0]);
3485 while (GetMessageA(&m,NULL,0,0))
3487 DispatchMessageA(&m);
3490 ExitProcess(m.wParam);
3494 SystemMonitors::SystemMonitors(void)
3499 iHaveMultiMonFunctions = false;
3501 if ((n = GetSystemMetrics(SM_CMONITORS)) <= 1)
3506 HMODULE huser32 = GetModuleHandleA("user32.dll");
3508 // Get pointers to the APIs we want
3509 if (huser32 == NULL ||
3510 (ipMonitorFromRect =
3511 (HMONITOR (WINAPI *)(LPCRECT lprcScreenCoords, UINT uFlags))
3512 GetProcAddress(huser32, "MonitorFromRect")) == NULL ||
3514 (BOOL (WINAPI *)(HMONITOR hMonitor, LPMONITORINFO lpMonitorInfo))
3515 GetProcAddress(huser32, "GetMonitorInfoA")) == NULL)
3521 iHaveMultiMonFunctions = true;
3524 TBool SystemMonitors::RectAllOnOne(RECT& rect)
3526 HMONITOR monitor = MonitorFromRect(rect);
3527 if (monitor == NULL)
3532 MONITORINFO monInfo;
3533 monInfo.cbSize = sizeof(MONITORINFO);
3535 if (! GetMonitorInfo(monitor, &monInfo))
3542 if (IntersectRect(&overlap, &rect, &monInfo.rcWork) &&
3543 EqualRect(&overlap, &rect))
3551 HMONITOR SystemMonitors::MonitorFromRect(const RECT& rect, UINT flags)
3553 if (! iHaveMultiMonFunctions)
3558 return (*ipMonitorFromRect)(&rect, flags);
3561 TBool SystemMonitors::GetMonitorInfo(HMONITOR monitor, LPMONITORINFO pMonInfo)
3563 if (! iHaveMultiMonFunctions)
3568 return (*ipGetMonitorInfo)(monitor, pMonInfo);
3573 HDC winDC = GetDC(TheWin[0]);
3575 hdcBits=CreateCompatibleDC(winDC);
3576 SelectObject(hdcBits,TheScreenBitmap[0]);
3577 HPEN pen=CreatePen(PS_SOLID,0,RGB(0,0,0));
3578 SelectObject(hdcBits,pen);
3580 LOGBRUSH redbrush={BS_SOLID, RGB(0xff,0,0)};
3581 LOGBRUSH greenbrush={BS_SOLID, RGB(0,0xff,0)};
3582 LOGBRUSH blackbrush={BS_SOLID, RGB(0,0,0)};
3584 if (LedMask & KLedMaskRed1)
3585 brush=CreateBrushIndirect(&redbrush);
3587 brush=CreateBrushIndirect(&blackbrush);
3588 SelectObject(hdcBits,brush);
3589 DWinsUi *ini=systemIni;
3590 Ellipse(hdcBits, ini->iLedOffsetX, ini->iLedOffsetY, ini->iLedOffsetX+ini->iLedSize, ini->iLedOffsetY+ini->iLedSize);
3591 DeleteObject(brush);
3593 if (LedMask & KLedMaskGreen1)
3594 brush=CreateBrushIndirect(&greenbrush);
3596 brush=CreateBrushIndirect(&blackbrush);
3597 SelectObject(hdcBits,brush);
3598 if (ini->iLedVertical)
3599 Ellipse(hdcBits, ini->iLedOffsetX, ini->iLedOffsetY+ini->iLedSize+ini->iLedGap,
3600 ini->iLedOffsetX+ini->iLedSize, ini->iLedOffsetY+ini->iLedSize+ini->iLedGap+ini->iLedSize);
3602 Ellipse(hdcBits, ini->iLedOffsetX+ini->iLedSize+ini->iLedGap, ini->iLedOffsetY,
3603 ini->iLedOffsetX+ini->iLedSize+ini->iLedGap+ini->iLedSize, ini->iLedOffsetY+ini->iLedSize);
3604 DeleteObject(brush);
3607 ReleaseDC(TheWin[0], winDC);
3608 if (ini->iLedVertical)
3610 RECT r={ini->iLedOffsetX,
3612 ini->iLedOffsetX+ini->iLedSize,
3613 ini->iLedOffsetY+ini->iLedSize+ini->iLedGap+ini->iLedSize};
3614 InvalidateRect(TheWin[0], &r, FALSE);
3618 RECT r={ini->iLedOffsetX,
3620 ini->iLedOffsetX+ini->iLedSize+ini->iLedGap+ini->iLedSize,
3621 ini->iLedOffsetY+ini->iLedSize};
3622 InvalidateRect(TheWin[0], &r, FALSE);
3626 void DWinsUi::ScreenInfo(TScreenInfoV01& aInfo)
3628 // Return screen 0 info to the window server.
3631 aInfo.iWindowHandleValid=ETrue;
3632 aInfo.iWindowHandle=TheChildWin[0];
3633 aInfo.iScreenAddressValid=EFalse;
3634 aInfo.iScreenAddress=NULL;
3635 aInfo.iScreenSize.iWidth = iScreens[0]->iMaxScreenWidth;
3636 aInfo.iScreenSize.iHeight = iScreens[0]->iMaxScreenHeight;
3640 TBool DWinsUi::VideoInfo(TInt aScreenNumber, TVideoInfoV01& aInfo)
3642 return VideoInfo(aScreenNumber,iScreens[aScreenNumber&KMaskScreenNum]->iCurrentMode,aInfo);
3645 /// Could fail if flip mode is not supported
3646 TBool DWinsUi::VideoInfo(TInt aScreenNumber,TInt aModeNumber, TVideoInfoV01& aInfo)
3648 aScreenNumber &= KMaskScreenNum;
3649 if (aScreenNumber>=iScreens.Count())
3651 if (masterIni->iBufferSet.Count() && masterIni->iBufferSet[aScreenNumber].iDisplayDriverCount > 0)
3653 return VideoInfoForDisplayDriver(aScreenNumber,aModeNumber,aInfo);
3657 if ((aModeNumber&KMaskModeNum)>=1)
3658 return EFalse; //non-gce emulator doesn't support changing the mode number.
3659 DScreenProperties* screenProperties=iScreens[aScreenNumber];
3660 aInfo.iSizeInPixels.iWidth = screenProperties->iMaxScreenWidth;
3661 aInfo.iSizeInPixels.iHeight = screenProperties->iMaxScreenHeight;
3662 aInfo.iSizeInTwips.iWidth = screenProperties->iMaxPhysicalScreenWidth ? screenProperties->iMaxPhysicalScreenWidth : TInt(screenProperties->iScreenWidth*KDefaultPixelsToTwipsX);
3663 aInfo.iSizeInTwips.iHeight = screenProperties->iMaxPhysicalScreenHeight ? screenProperties->iMaxPhysicalScreenHeight : TInt(screenProperties->iScreenHeight*KDefaultPixelsToTwipsY);
3664 aInfo.iIsMono = EFalse;
3665 aInfo.iIsPalettized = EFalse;
3666 aInfo.iDisplayMode=screenProperties->iCurrentMode;
3667 aInfo.iIsPixelOrderRGB = ETrue;
3668 aInfo.iIsPixelOrderLandscape=ETrue;
3670 aInfo.iVideoAddress = (TInt)TheChildWin[aScreenNumber];
3671 aInfo.iBitsPerPixel = screenProperties->iColorDepth;
3672 aInfo.iOffsetToFirstPixel=0;
3673 aInfo.iOffsetBetweenLines=0;
3678 /** Could fail if flip mode is not supported.
3679 Note that this method is inteneded to be called directly to parameterise the setting up of the display driver,
3680 so it must survive absense of the display driver installation!
3683 TBool DWinsUi::VideoInfoForDisplayDriver(TInt aScreenNumber,TInt aModeNumber, TVideoInfoV01& aInfo, TBool aRealWidthAndHeight)
3685 aScreenNumber &= KMaskScreenNum;
3686 DScreenProperties* screenProperties = iScreens[aScreenNumber];
3687 if ((aModeNumber&KMaskModeNum) >= screenProperties->iMaxModes)
3692 aInfo.iSizeInPixels.iWidth = aRealWidthAndHeight ? screenProperties->iScreenWidth : screenProperties->iMaxScreenWidth;
3693 aInfo.iSizeInPixels.iHeight = aRealWidthAndHeight ? screenProperties->iScreenHeight : screenProperties->iMaxScreenHeight;
3695 if (aRealWidthAndHeight==EFalse)
3697 aInfo.iSizeInTwips.iWidth = screenProperties->iMaxPhysicalScreenWidth ? screenProperties->iMaxPhysicalScreenWidth : TInt(screenProperties->iScreenWidth*KDefaultPixelsToTwipsX);
3698 aInfo.iSizeInTwips.iHeight = screenProperties->iMaxPhysicalScreenHeight ? screenProperties->iMaxPhysicalScreenHeight : TInt(screenProperties->iScreenHeight*KDefaultPixelsToTwipsY);
3702 aInfo.iSizeInTwips.iWidth = screenProperties->iPhysicalScreenWidth ? screenProperties->iPhysicalScreenWidth : TInt(screenProperties->iScreenWidth*KDefaultPixelsToTwipsX);
3703 aInfo.iSizeInTwips.iHeight = screenProperties->iPhysicalScreenHeight ? screenProperties->iPhysicalScreenHeight : TInt(screenProperties->iScreenHeight*KDefaultPixelsToTwipsY);
3706 aInfo.iIsMono = EFalse;
3707 aInfo.iIsPalettized = EFalse;
3708 aInfo.iDisplayMode=screenProperties->iCurrentMode;
3709 aInfo.iIsPixelOrderRGB = ETrue;
3710 aInfo.iIsPixelOrderLandscape=ETrue;
3712 // Set memory to iVideoAddress to NULL to trigger the HAL code into querying the video address
3714 aInfo.iVideoAddress = NULL;
3716 TInt bpp=screenProperties->iModeDepths[aModeNumber&KMaskModeNum];
3717 aInfo.iBitsPerPixel=bpp;
3720 bpp=(bpp+15)&-16; //12 & 16 --> 16 ; 24 & 32 --> 32
3723 aInfo.iOffsetToFirstPixel=0;
3724 #ifdef TEST_GCE_VARIABLE_START_EXTRA
3725 aInfo.iOffsetToFirstPixel+= TEST_GCE_VARIABLE_START_EXTRA*(1+aModeNumber&KMaskScreenModeNum);
3726 if ((aModeNumber& KModeFlagFlipped)
3728 #ifndef ASSYMETRIC_SQUARE_STRIDE
3729 if (aInfo.iSizeInPixels.iWidth!=aInfo.iSizeInPixels.iHeight)
3731 aInfo.iOffsetToFirstPixel+= TEST_GCE_VARIABLE_START_EXTRA*KEmulMaxNumModes;
3734 if (aModeNumber& KModeFlagFlipped)
3736 // we calculate the number of bytes per scanline that MUST be a multiple of 32 bits word (alignment)
3737 // screenProperties->iMaxScreenHeight * bpp represnts the number of bits per scanline
3738 // +31 is the ceiling
3739 // we shift right (>>3) because there are 8 bits/byte
3740 // we mask with ~3 because we are intrested in the octet value
3741 aInfo.iOffsetBetweenLines=((screenProperties->iMaxScreenHeight * bpp + 31) >> 3) & ~3;
3745 // please see the comment above
3746 aInfo.iOffsetBetweenLines=((screenProperties->iMaxScreenWidth * bpp + 31) >> 3) & ~3;
3748 #ifdef TEST_GCE_VARIABLE_STRIDE_EXTRA
3749 aInfo.iOffsetBetweenLines+=TEST_GCE_VARIABLE_STRIDE_EXTRA;
3755 TInt DMasterIni::DoHalFunction(TAny* aPtr, TInt aFunction, TAny* a1, TAny* a2)
3757 return masterIni->HalFunction((TInt)aPtr,aFunction,a1,a2);
3761 TInt DMasterIni::HalFunction(TInt aDeviceNumber, TInt aFunction, TAny* a1, TAny* a2)
3763 if (TUint(aDeviceNumber) >= TUint(systemIni->iScreens.Count()))
3764 return KErrArgument;
3771 case EDisplayHalScreenInfo:
3773 TPckgBuf<TScreenInfoV01> vPckg;
3774 systemIni->ScreenInfo(vPckg());
3775 Kern::InfoCopy(*(TDes8*)a1,vPckg);
3778 case EDisplayHalWsRegisterSwitchOnScreenHandling:
3779 WsSwitchOnScreen=(TBool)a1;
3781 case EDisplayHalSetState:
3783 if(!Kern::CurrentThreadHasCapability(ECapabilityPowerMgmt,__PLATSEC_DIAGNOSTIC_STRING("Checked by Hal function EDisplayHalSetState")))
3784 return KErrPermissionDenied;
3786 WinsGuiPowerHandler->ScreenOn(aDeviceNumber);
3788 WinsGuiPowerHandler->ScreenOff(aDeviceNumber);
3792 case EDisplayHalState:
3793 *(TInt*)a1=!systemIni->iScreens[aDeviceNumber]->iScreenOff;
3795 case EDisplayHalWsSwitchOnScreen:
3796 WinsGuiPowerHandler->ScreenOn();
3798 case EDisplayHalMaxDisplayContrast:
3799 kumemput32(a1,&KMaxDisplayContrast,sizeof(KMaxDisplayContrast));
3801 case EDisplayHalDisplayContrast:
3802 kumemput32(a1,&systemIni->iScreens[aDeviceNumber]->iDisplayContrast,sizeof(systemIni->iScreens[aDeviceNumber]->iDisplayContrast));
3804 case EDisplayHalSetDisplayContrast:
3805 if(!Kern::CurrentThreadHasCapability(ECapabilityWriteDeviceData,__PLATSEC_DIAGNOSTIC_STRING("Checked by Hal function EDisplayHalSetDisplayContrast")))
3806 return KErrPermissionDenied;
3807 if (TUint(a1) <= TUint(KMaxDisplayContrast))
3808 systemIni->iScreens[aDeviceNumber]->iDisplayContrast = TInt(a1);
3812 case EDisplayHalBacklightOn:
3815 kumemput32(a1,&c,sizeof(TBool));
3819 case EDisplayHalCurrentModeInfo:
3821 //a1 has ptr to buffer for results
3822 TPckgBuf<TVideoInfoV01> vPckg;
3823 if (systemIni->VideoInfo(aDeviceNumber, vPckg()))
3824 Kern::InfoCopy(*(TDes8*)a1,vPckg);
3830 case EDisplayHalSpecifiedModeInfo:
3832 kumemget32(&mode, a1, sizeof(mode));
3833 TPckgBuf<TVideoInfoV01> vPckg;
3834 if (!systemIni->VideoInfo(aDeviceNumber, mode, vPckg()))
3835 return KErrArgument;
3836 Kern::InfoCopy(*(TDes8*)a2, vPckg);
3840 case EDisplayHalSetMode:
3841 // if(!Kern::CurrentThreadHasCapability(ECapabilityMultimediaDD,__PLATSEC_DIAGNOSTIC_STRING("Checked by Hal function EDisplayHalSetMode")))
3842 // return KErrPermissionDenied;
3844 //Note that at present the HAL mode does not apparently get set when the CFbsScreenDevice requires a different mode.
3845 //At least in the emulator and default h4 implementation...
3847 mode=KMaskModeNum&(TInt) a1;
3849 //can't avoid this behaviour change test against gce loaded
3850 if (masterIni->iBufferSet.Count() && masterIni->iBufferSet[aDeviceNumber].iDisplayDriverCount > 0)
3851 maxMode=systemIni->iScreens[aDeviceNumber]->iMaxModes;
3852 if (mode >=maxMode || mode<0)
3857 //Harmless/Pointless in vanilla wins mode.
3858 systemIni->iScreens[aDeviceNumber]->iCurrentMode=mode;
3862 case EDisplayHalMode:
3864 //This is always 0 in non-gce emulator
3865 kumemput32(a1,&systemIni->iScreens[aDeviceNumber]->iCurrentMode,sizeof(systemIni->iScreens[aDeviceNumber]->iCurrentMode));
3869 case EDisplayHalModeCount:
3871 //Need to actually count them here!
3872 //GCE will ignore modes<=8
3874 if (masterIni->iBufferSet.Count() && masterIni->iBufferSet[aDeviceNumber].iDisplayDriverCount > 0)
3875 encodedMode=systemIni->iScreens[aDeviceNumber]->iMaxModes;
3876 kumemput32(a1,&encodedMode,sizeof(encodedMode));
3880 case EDisplayHalColors:
3883 if (masterIni->iBufferSet.Count()==0 || masterIni->iBufferSet[aDeviceNumber].iDisplayDriverCount <= 0)
3885 deepestMode = KMaxDisplayColors; //I could try and work it out, but this is what used to happen!
3890 for (TInt i=0,maxI=systemIni->iScreens[aDeviceNumber]->iMaxModes;i<maxI;i++)
3891 if (systemIni->iScreens[aDeviceNumber]->iModeDepths[i]>maxBpp)
3892 maxBpp=systemIni->iScreens[aDeviceNumber]->iModeDepths[i];
3893 deepestMode= 1<<maxBpp;
3896 kumemput32(a1,&deepestMode,sizeof(deepestMode));
3899 case EDisplayHalGetDisplayMemoryHandle:
3903 kumemget32(&passedIn, a1, sizeof(TInt));
3904 if (passedIn != -1) //not from a getall
3906 NKern::ThreadEnterCS();
3907 if (!(masterIni->iBufferSet.Count() == 0 || masterIni->iBufferSet[aDeviceNumber].iDisplayDriverCount <= 0 ))
3909 r = masterIni->DisplayMemoryHandle(aDeviceNumber, val);
3915 NKern::ThreadLeaveCS();
3917 kumemput32(a1, &val, sizeof(TInt));
3922 case EDisplayHalGetDisplayMemoryAddress:
3926 kumemget32(&passedIn, a1, sizeof(TInt));
3927 if (passedIn != -1) //not from a getall
3929 if (!(masterIni->iBufferSet.Count() == 0 || masterIni->iBufferSet[aDeviceNumber].iDisplayDriverCount <= 0 ))
3931 r = masterIni->DisplayMemoryAddress(aDeviceNumber, val);
3938 kumemput32(a1, &val, sizeof(TInt));
3942 case EDisplayHalNumberOfResolutions:
3944 r = NumberOfResolutions(aDeviceNumber, a1, a2);
3947 case EDisplayHalSpecificScreenInfo:
3949 r = SpecificScreenInfo(aDeviceNumber, a1, a2);
3952 case EDisplayHalCurrentScreenInfo:
3954 r = CurrentScreenInfo(aDeviceNumber, a1, a2);
3957 case EDisplayHalSetDisplayState:
3959 //increase the spinner at both beginning and end of resetting the display state
3960 NKern::LockedInc(iBufferSet[aDeviceNumber].iStateChangeCount);
3961 kumemget32(&iBufferSet[aDeviceNumber].iDisplayState, a1, sizeof(TInt));
3963 switch(iBufferSet[aDeviceNumber].iDisplayState)
3967 case ESingleResolution:
3968 // the fascia effect of 0x0 resolution
3969 SetDisplaySize(aDeviceNumber, 0, 0);
3973 NKern::LockedInc(iBufferSet[aDeviceNumber].iStateChangeCount);
3976 case EDisplayHalGetStateSpinner:
3978 kumemput32(a1,&iBufferSet[aDeviceNumber].iStateChangeCount,
3979 sizeof(iBufferSet[aDeviceNumber].iStateChangeCount));
3989 TInt DMasterIni::NumberOfResolutions(TInt aDeviceNumber, TAny* a1, TAny* a2)
3991 TInt numberOfConfigs;
3992 switch(iBufferSet[aDeviceNumber].iDisplayState)
3996 numberOfConfigs = 0;
4001 return KErrDisconnected;
4004 case ESingleResolution:
4006 numberOfConfigs = 1;
4009 case ENormalResolution:
4012 numberOfConfigs = iSystemInis.Count();
4013 if (numberOfConfigs > 1)
4015 TVideoInfoV01 info1;
4016 TVideoInfoV01 info2;
4017 iSystemInis[0]->VideoInfoForDisplayDriver(aDeviceNumber, 0, info1, ETrue);
4018 iSystemInis[1]->VideoInfoForDisplayDriver(aDeviceNumber, 0, info2, ETrue);
4019 if (info1.iSizeInPixels.iWidth == info2.iSizeInPixels.iWidth &&
4020 info1.iSizeInPixels.iHeight == info2.iSizeInPixels.iHeight)
4022 numberOfConfigs = 1; //It looks like all resolutions for this device are the same
4027 kumemput32(a1,&numberOfConfigs,sizeof(numberOfConfigs));
4030 kumemput32(a2,&(iBufferSet[aDeviceNumber].iStateChangeCount),sizeof(iBufferSet[aDeviceNumber].iStateChangeCount));
4035 TInt DMasterIni::SpecificScreenInfo(TInt aDeviceNumber, TAny* a1, TAny* a2)
4038 switch(iBufferSet[aDeviceNumber].iDisplayState)
4040 case ENoResolution: //Do Nothing
4044 return KErrDisconnected;
4047 case ESingleResolution: //fill (0,0) as the only element in resolution array
4052 info.iSizeInPixels.iHeight = 0;
4053 info.iSizeInPixels.iWidth = 0;
4054 info.iSizeInTwips.iHeight = 0;
4055 info.iSizeInTwips.iWidth = 0;
4056 TPtr8 infoPtr((TUint8*)&info, sizeof(info), sizeof(info));
4057 Kern::InfoCopy(*(TDes8*)a2, infoPtr);
4061 case ENormalResolution:
4064 kumemget32(&config, a1, sizeof(config));
4065 TPckgBuf<TVideoInfoV01> vPckg;
4066 iSystemInis[config]->VideoInfoForDisplayDriver(aDeviceNumber, 0, vPckg(), ETrue);
4067 Kern::InfoCopy(*(TDes8*)a2,vPckg);
4073 TInt DMasterIni::CurrentScreenInfo(TInt aDeviceNumber, TAny* a1, TAny* /*a2*/)
4075 switch(iBufferSet[aDeviceNumber].iDisplayState)
4077 case ENoResolution: //Do Nothing
4081 return KErrDisconnected;
4084 case ESingleResolution: //fill (0,0)
4087 info.iSizeInPixels.iHeight = 0;
4088 info.iSizeInPixels.iWidth = 0;
4089 info.iSizeInTwips.iHeight = 0;
4090 info.iSizeInTwips.iWidth = 0;
4091 TPtr8 infoPtr((TUint8*)&info, sizeof(info), sizeof(info));
4092 Kern::InfoCopy(*(TDes8*)a1, infoPtr);
4095 case ENormalResolution:
4098 TPckgBuf<TVideoInfoV01> vPckg;
4099 systemIni->VideoInfoForDisplayDriver(aDeviceNumber, 0, vPckg(), ETrue);
4100 Kern::InfoCopy(*(TDes8*)a1,vPckg);
4106 TInt DMasterIni::DoXYHalFunction(TAny* aThis, TInt aFunction, TAny* a1, TAny* a2)
4108 return static_cast<DMasterIni*>(aThis)->XYHalFunction(aFunction,a1,a2);
4111 TInt DMasterIni::XYHalFunction(TInt aFunction, TAny* a1, TAny* /*a2*/)
4116 case EDigitiserHalXYInfo:
4118 if(systemIni->iXYInputType==EXYInputPointer)
4120 TPckgBuf<TDigitiserInfoV01> vPckg;
4121 TDigitiserInfoV01& xyinfo=vPckg();
4122 xyinfo.iDigitiserSize.iWidth=max(systemIni->iScreens[0]->iXYInputWidth,systemIni->iScreens[0]->iMaxScreenWidth+systemIni->iScreens[0]->iScreenOffsetX);
4123 xyinfo.iDigitiserSize.iHeight=max(systemIni->iScreens[0]->iXYInputHeight,systemIni->iScreens[0]->iMaxScreenHeight+systemIni->iScreens[0]->iScreenOffsetY);
4124 xyinfo.iOffsetToDisplay.iX=systemIni->iScreens[0]->iScreenOffsetX;
4125 xyinfo.iOffsetToDisplay.iY=systemIni->iScreens[0]->iScreenOffsetY;
4126 Kern::InfoCopy(*(TDes8*)a1,vPckg);
4139 TInt DMasterIni::DoMouseHalFunction(TAny* aThis, TInt aFunction, TAny* a1, TAny* a2)
4141 return static_cast<DMasterIni*>(aThis)->MouseHalFunction(aFunction,a1,a2);
4144 TInt DMasterIni::MouseHalFunction(TInt aFunction, TAny* a1, TAny* /*a2*/)
4149 case EMouseHalMouseInfo:
4151 if(systemIni->iXYInputType==EXYInputMouse || systemIni->iXYInputType==EXYInputDeltaMouse)
4153 TPckgBuf<TMouseInfoV01> vPckg;
4154 TMouseInfoV01& xyinfo=vPckg();
4155 xyinfo.iMouseButtons=2;
4156 xyinfo.iMouseAreaSize.iWidth=max(systemIni->iScreens[0]->iXYInputWidth,systemIni->iScreens[0]->iMaxScreenWidth+systemIni->iScreens[0]->iScreenOffsetX);
4157 xyinfo.iMouseAreaSize.iHeight=max(systemIni->iScreens[0]->iXYInputHeight,systemIni->iScreens[0]->iMaxScreenHeight+systemIni->iScreens[0]->iScreenOffsetY);
4158 xyinfo.iOffsetToDisplay.iX=systemIni->iScreens[0]->iScreenOffsetX;
4159 xyinfo.iOffsetToDisplay.iY=systemIni->iScreens[0]->iScreenOffsetY;
4160 Kern::InfoCopy(*(TDes8*)a1,vPckg);
4173 TInt DMasterIni::DoKbdHalFunction(TAny* /*aThis*/, TInt aFunction, TAny* /*a1*/, TAny* /*a2*/)
4175 // don't actually do anything, just enough to report a Keyboard is present
4177 if(aFunction!=EKeyboardHalKeyboardInfo)
4184 // Window has been minimised.
4189 v.Set(TRawEvent::EInactive);
4193 void UpdateModifiers()
4194 //Updates the modifier key states and sends an event to wserv about the
4199 if(GetKeyState(VK_SCROLL)&1)
4200 modifiers|=EModifierScrollLock;
4201 if(GetKeyState(VK_NUMLOCK)&1)
4202 modifiers|=EModifierNumLock;
4203 if(GetKeyState(VK_CAPITAL)&1)
4204 modifiers|=EModifierCapsLock;
4205 v.Set(TRawEvent::EUpdateModifiers,modifiers);
4211 // Window has been restored.
4212 // Update the toggling modifiers, reset any others
4217 v.Set(TRawEvent::EActive);
4228 TInt DWinsUi::GetVirtualKey(TEmulCommand& aCommand, TInt aX, TInt aY)
4230 //if the point is in the list of shapes, set the key and return true
4231 for (TInt keyCount = iVirtualKeys.Count(); --keyCount >= 0; )
4233 const VirtualKey& vk = *iVirtualKeys[keyCount];
4234 if (vk.Contains(aX, aY))
4236 aCommand = vk.Command();
4243 void DWinsUi::TranslateMouseCoords(const TEmulatorFlip aFlipState, const TInt aX, const TInt aY, const TInt aRegionWidth, const TInt aRegionHeight, TInt& aNewX, TInt& aNewY)
4247 case EEmulatorFlipRestore:
4252 case EEmulatorFlipInvert:
4253 aNewX = aRegionWidth - aX;
4254 aNewY = aRegionHeight - aY;
4257 case EEmulatorFlipLeft:
4258 aNewX = aRegionWidth - aY;
4262 case EEmulatorFlipRight:
4264 aNewY = aRegionHeight - aX;
4270 TBool DWinsUi::OnScreen(TInt aScreen, TInt ax, TInt ay) const
4272 // Checks if a point within the Emulator window is on the screen
4275 return (TUint(ax) < TUint(systemIni->iScreens[aScreen]->iScreenWidth) && TUint(ay) < TUint(systemIni->iScreens[aScreen]->iScreenHeight));
4278 TInt DWinsUi::Create(TInt aId)
4280 TInt r = SetupProperties(aId);
4284 DScreenProperties* currentScreen = NULL;
4285 for(screen=0;screen<iScreens.Count();screen++)
4287 BITMAPINFOHEADER bitmapinfo;
4288 currentScreen = iScreens[screen];
4289 if (readBitmapInfo(&bitmapinfo, currentScreen->iFasciaFileName) == KErrNone)
4291 currentScreen->iXYInputWidth=bitmapinfo.biWidth;
4292 currentScreen->iXYInputHeight=bitmapinfo.biHeight;
4294 currentScreen->iXYInputWidth=max(currentScreen->iXYInputWidth,currentScreen->iScreenWidth+currentScreen->iScreenOffsetX);
4295 currentScreen->iXYInputHeight=max(currentScreen->iXYInputHeight,currentScreen->iScreenHeight+currentScreen->iScreenOffsetY);
4298 currentScreen = iScreens[0];
4299 //note digitizer offsets are relative to EPOC screen 0
4300 if (-1 == iDigitizerWidth)
4301 iDigitizerWidth = currentScreen->iXYInputWidth -
4302 (currentScreen->iScreenOffsetX + iDigitizerOffsetX);
4304 currentScreen->iXYInputWidth=max(currentScreen->iXYInputWidth,iDigitizerWidth);
4306 if (-1 == iDigitizerHeight)
4307 iDigitizerHeight = currentScreen->iXYInputHeight -
4308 (currentScreen->iScreenOffsetY + iDigitizerOffsetY);
4310 currentScreen->iXYInputHeight=max(currentScreen->iXYInputHeight,iDigitizerHeight);
4315 const RDisplayChannel::TPixelFormat DMasterIni::iSupportedPixelFormatTable[] =
4317 EUidPixelFormatXRGB_8888,
4318 EUidPixelFormatARGB_8888,
4319 EUidPixelFormatARGB_8888_PRE,
4320 EUidPixelFormatXRGB_4444,
4321 EUidPixelFormatARGB_4444,
4322 EUidPixelFormatRGB_565
4325 const TInt DMasterIni::iSupportedPixelFormatTableSize = static_cast<TInt>(sizeof(iSupportedPixelFormatTable)/
4326 sizeof(iSupportedPixelFormatTable[0]));
4328 void DMasterIni::InitBufferFormat(DScreenProperties& aScreenProperties, RDisplayChannel::TBufferFormat& aBufferFormat)
4330 TUint bitsPerPixel = MaximumBitDepthFromMask(aScreenProperties.iColorDepth);
4332 aBufferFormat.iSize.iWidth = aScreenProperties.iMaxScreenWidth;
4333 aBufferFormat.iSize.iHeight = aScreenProperties.iMaxScreenHeight;
4334 switch (bitsPerPixel)
4336 case 12: // XRGB4444
4337 aBufferFormat.iPixelFormat = EUidPixelFormatXRGB_4444;
4340 aBufferFormat.iPixelFormat = EUidPixelFormatRGB_565;
4342 case 24: // Really 32bpp, but top 8 unused
4343 case 32: // While 32bpp, top 8 will not be used
4345 aBufferFormat.iPixelFormat = EUidPixelFormatXRGB_8888;
4350 TInt DMasterIni::Create()
4352 TInt configurations = Property::GetInt("ConfigCount", 0);
4353 if (configurations == 0)
4356 // the pixel formats table is, at present, configuration independent
4359 for (count = 0; count < configurations && r == KErrNone; ++count)
4361 DWinsUi* dwi = new DWinsUi;
4363 r = dwi->Create(count);
4366 iSystemInis.Append(dwi);
4371 systemIni = masterIni->iSystemInis[0];
4373 WinsGuiPowerHandler = DWinsGuiPowerHandler::New();
4374 if (!WinsGuiPowerHandler)
4375 return KErrNoMemory;
4377 TheWin=new HWND[systemIni->iScreens.Count()];
4378 TheChildWin=new HWND[systemIni->iScreens.Count()];
4379 TheScreenBitmap=new HBITMAP[systemIni->iScreens.Count()];
4380 CurrentFlipState=new TEmulatorFlip[systemIni->iScreens.Count()];
4382 if(!TheWin || !TheChildWin || !TheScreenBitmap || !CurrentFlipState)
4383 return KErrNoMemory;
4384 memset(CurrentFlipState,EEmulatorFlipRestore,systemIni->iScreens.Count());
4387 buffer.iDisplayDriverCount = 0;
4388 buffer.iDisplayState = ENormalResolution;
4389 buffer.iDisplayBuffer = 0;
4390 buffer.iDisplayChannel = NULL;
4394 for(i=0;i<systemIni->iScreens.Count();i++)
4396 DScreenProperties *pScr = systemIni->iScreens[i];
4398 masterIni->InitBitmapHeader(*pScr, &buffer.iInfo);
4399 masterIni->InitBufferFormat(*pScr, buffer.iBufferFormat);
4401 r = masterIni->iBufferSet.Append(buffer);
4406 if (CreateWin32Thread(EThreadEvent, &KernelWindowThread, NULL, ETrue) == NULL)
4409 for(i=0;i<systemIni->iScreens.Count();i++)
4411 r = Kern::AddHalEntry(EHalGroupDisplay,&DoHalFunction,(TAny*)i,i);
4416 // should really come from Keyboard driver, but not doing it now...
4417 r = Kern::AddHalEntry(EHalGroupKeyboard,&DoKbdHalFunction,this);
4421 if(systemIni->iXYInputType==EXYInputPointer)
4423 r = Kern::AddHalEntry(EHalGroupDigitiser,&DoXYHalFunction,this);
4427 else if(systemIni->iXYInputType==EXYInputMouse || systemIni->iXYInputType==EXYInputDeltaMouse)
4429 r = Kern::AddHalEntry(EHalGroupMouse,&DoMouseHalFunction,this);
4437 void DMasterIni::InitBitmapHeader(DScreenProperties& aScreenProperties, LPBITMAPV4HEADER aInfo)
4439 TInt width = aScreenProperties.iMaxScreenWidth;
4440 TInt height = aScreenProperties.iMaxScreenHeight;
4441 TUint bitsPerPixel = MaximumBitDepthFromMask(aScreenProperties.iColorDepth);
4443 memset(aInfo, 0, sizeof(BITMAPV4HEADER));
4445 switch (bitsPerPixel)
4447 case 12: // XRGB4444
4448 aInfo->bV4BitCount = 16;
4449 aInfo->bV4V4Compression = BI_BITFIELDS;
4450 aInfo->bV4RedMask = 0x0F00;
4451 aInfo->bV4GreenMask = 0x00F0;
4452 aInfo->bV4BlueMask = 0x000F;
4455 aInfo->bV4BitCount = 16;
4456 aInfo->bV4V4Compression = BI_BITFIELDS;
4457 aInfo->bV4RedMask = 0xF800;
4458 aInfo->bV4GreenMask = 0x07E0;
4459 aInfo->bV4BlueMask = 0x001F;
4461 case 24: // Really 32bpp, but top 8 unused
4462 case 32: // While 32bpp, top 8 will not be used
4464 aInfo->bV4BitCount = 32;
4465 aInfo->bV4V4Compression = BI_RGB;
4466 // Mask is implicit for BI_RGB compression
4470 aInfo->bV4Size = sizeof(BITMAPV4HEADER);
4471 aInfo->bV4Width = width;
4472 aInfo->bV4Height = -height; // Bitmap runs top to bottom
4473 aInfo->bV4Planes = 1;
4475 TInt bpp = _ALIGN_UP(aInfo->bV4BitCount, 16); //12 & 16 --> 16 ; 24 & 32 --> 32
4476 TInt widthInPixel = aInfo->bV4Width * bpp;
4477 //rounding to 32 bits (4 octets) and converting, then, bits to octets;
4478 TInt scanLineInBytes = _ALIGN_UP(widthInPixel, 32) >> 3;
4479 aInfo->bV4SizeImage = -aInfo->bV4Height * scanLineInBytes;
4481 // Set color space as uncalibrated. All other members are then ignored.
4482 #if defined(LCS_DEVICE_RGB)
4483 aInfo->bV4CSType = LCS_DEVICE_RGB;
4484 #elif defined(LCS_sRGB)
4485 aInfo->bV4CSType = LCS_sRGB;
4489 // Helper function that allocates a single frame buffer.
4490 static TInt AllocateOneFrameBuffer(TInt aSize, TScreenBuffer &aScreenBuffer)
4492 // Open shared chunk to the composition framebuffer
4494 // round to page size
4496 return KErrArgument;
4497 TUint round = Kern::RoundToPageSize(aSize);
4498 TLinAddr chunkKernelAddr = 0;
4499 TUint32 physicalAddress = 0;
4500 TUint32 chunkMapAttr = 0;
4502 // create shared chunk
4503 NKern::ThreadEnterCS();
4505 TChunkCreateInfo info;
4506 info.iType = TChunkCreateInfo::ESharedKernelMultiple;
4507 info.iMaxSize = round;
4509 info.iOwnsMemory = ETrue;
4510 info.iDestroyedDfc = 0;
4512 TInt r = Kern::ChunkCreate(info, chunk, chunkKernelAddr, chunkMapAttr);
4515 // map our chunk to specific
4516 r = Kern::ChunkCommitContiguous(chunk, 0, aSize, physicalAddress);
4519 Kern::ChunkClose(chunk);
4525 TBufferAddressA* bufferAddress = new TBufferAddressA;
4532 bufferAddress->iAddress = (TAny*)chunkKernelAddr;
4533 bufferAddress->iChunk = chunk;
4535 if ((r = aScreenBuffer.iFrameBuffers.Append(bufferAddress->iAddress)) == KErrNone)
4537 r = aScreenBuffer.iMemChunks.Append(bufferAddress);
4543 Kern::ChunkClose(chunk);
4545 NKern::ThreadLeaveCS();
4549 TInt DMasterIni::AllocateFrameBuffers(TInt aScreenNumber, TInt aCount, TInt aSize)
4553 TInt r = AllocateOneFrameBuffer(aSize, masterIni->iBufferSet[aScreenNumber].iScreenBuffer);
4562 void DMasterIni::ReleaseFrameBuffers(TInt aScreenNumber)
4564 RPointerArray<TAny>& frameBuffers = masterIni->iBufferSet[aScreenNumber].iScreenBuffer.iFrameBuffers;
4565 RPointerArray<TBufferAddressA>& memChunks = masterIni->iBufferSet[aScreenNumber].iScreenBuffer.iMemChunks;
4566 RPointerArray<TBufferAddressA>& dsaChunks = masterIni->iBufferSet[aScreenNumber].iDsaBuffer.iMemChunks;
4568 NKern::ThreadEnterCS();
4570 TInt count = memChunks.Count();
4571 for (index = 0; index < count; index++)
4573 Kern::ChunkClose(memChunks[index]->iChunk);
4575 count = dsaChunks.Count();
4576 for (index = 0; index < count; index++)
4578 Kern::ChunkClose(dsaChunks[index]->iChunk);
4580 NKern::ThreadLeaveCS();
4582 frameBuffers.Reset();
4588 TProcessAddrEntry::TProcessAddrEntry(DProcess *aProcess, TUint8* aAddress):
4589 iProcess(aProcess), iAddress(aAddress)
4595 Contruct a Shared Chunk cleanup object which will be used to clean up
4596 after the process/address table entry.
4598 TChunkCleanup::TChunkCleanup(DProcess* aProcess, TInt aScreenNumber)
4599 : TDfc((TDfcFn)TChunkCleanup::ChunkDestroyed,this,Kern::SvMsgQue(),0)
4600 , iProcess(aProcess)
4601 , iScreenNumber(aScreenNumber)
4606 Cancel the action of the cleanup object.
4608 void TChunkCleanup::Cancel()
4610 // Clear iProcess which means that when the DFC gets queued on chunk destruction
4611 // our ChunkDestroyed method will do nothing other than cleanup itself.
4616 Callback function called when the DFC runs, i.e. when a chunk is destroyed.
4618 void TChunkCleanup::ChunkDestroyed(TChunkCleanup* aSelf)
4620 DProcess* process = aSelf->iProcess;
4621 TInt screenNumber = aSelf->iScreenNumber;
4622 TUint index = aSelf->iIndex;
4623 // If we haven't been Cancelled...
4624 if(process && index != -1)
4626 if (masterIni->iBufferSet[screenNumber].iProcAddrTable[index].iProcess == process)
4628 masterIni->iBufferSet[screenNumber].iProcAddrTable[index].iProcess = 0;
4632 __KTRACE_OPT(KEXTENSION,Kern::Printf("Oops! Someone has messed up our process index!"));
4636 // We've finished so now delete ourself
4641 TInt DMasterIni::DisplayMemoryHandle(TInt aScreenNumber, TInt& aHandle)
4643 if (iBufferSet[aScreenNumber].iDsaBuffer.iMemChunks.Count() == 0)
4646 r = AllocateOneFrameBuffer(iMaxSizeInBytes, iBufferSet[aScreenNumber].iDsaBuffer);
4651 __ASSERT_DEBUG(iBufferSet[aScreenNumber].iDisplayChannel, Fault(EGuiNoDisplayChannel));
4652 iBufferSet[aScreenNumber].iDisplayChannel->SetLegacyBuffer(iBufferSet[aScreenNumber].iDsaBuffer.iFrameBuffers[0]);
4655 aHandle = Kern::MakeHandleAndOpen(&Kern::CurrentThread(),
4656 iBufferSet[aScreenNumber].iDsaBuffer.iMemChunks[0]->iChunk);
4668 // Find the address of the display memory.
4669 TInt DMasterIni::DisplayMemoryAddress(TInt aScreenNumber, TInt& aAddress)
4671 TBufferSet &bufferSet = iBufferSet[aScreenNumber];
4672 DProcess *process = &Kern::CurrentProcess();
4673 TInt firstFree = -1;
4674 NKern::FMWait(&iLock);
4675 TUint count = bufferSet.iProcAddrTable.Count();
4676 for(TUint i = 0; i < count; ++i)
4678 DProcess *curProcess = bufferSet.iProcAddrTable[i].iProcess;
4679 if (curProcess == process)
4681 aAddress = reinterpret_cast<TInt>(bufferSet.iProcAddrTable[i].iAddress);
4682 NKern::FMSignal(&iLock);
4685 if (curProcess == 0 && firstFree == -1)
4690 NKern::FMSignal(&iLock);
4691 // If we get here, we couldn't find the process in the iProcAddrTable.
4692 // Create a new Process Address entry.
4694 // Create a dummy chunk so that we can detect when the process dies,
4695 // give a handle to the user [but don't actually let the process KNOW what the handle is
4696 // so the user process can't do anything silly with the chunk]. Close our side of the
4697 // chunk to make sure there is only one reference to it.
4699 // find page size for one page.
4700 TUint round = Kern::RoundToPageSize(1);
4701 TLinAddr chunkKernelAddr = 0;
4702 TUint32 chunkMapAttr = 0;
4704 // create shared chunk
4705 NKern::ThreadEnterCS();
4706 // Cleanup object, used to issue a DFC when the chunk is closed (and
4707 // as the handle of the chunk is not given to the process, it can only
4708 // be closed when the process terminates!)
4709 TChunkCleanup *cleanup = new TChunkCleanup(process, aScreenNumber);
4712 NKern::ThreadLeaveCS();
4713 return KErrNoMemory;
4716 TChunkCreateInfo info;
4717 info.iType = TChunkCreateInfo::ESharedKernelMultiple;
4718 info.iMaxSize = round;
4720 info.iOwnsMemory = ETrue;
4721 info.iDestroyedDfc = cleanup;
4723 TInt r = Kern::ChunkCreate(info, chunk, chunkKernelAddr, chunkMapAttr);
4728 NKern::ThreadLeaveCS();
4733 // Create a new handle for the user thread.
4734 r = Kern::MakeHandleAndOpen(&Kern::CurrentThread(), chunk);
4735 Kern::ChunkClose(chunk);
4738 NKern::ThreadLeaveCS();
4743 // Create a second handle for the chunk to the DSA buffer.
4744 // First part: Make sure there is a DisplayMemoryHandle;
4746 r = DisplayMemoryHandle(aScreenNumber, handle);
4749 Kern::ChunkClose(chunk);
4750 NKern::ThreadLeaveCS();
4754 DChunk *dsaChunk = bufferSet.iDsaBuffer.iMemChunks[0]->iChunk;
4757 // Get the base addrss and insert into table.
4758 TUint8* baseAddress = Kern::ChunkUserBase(dsaChunk, &Kern::CurrentThread());
4759 NKern::FMWait(&iLock);
4760 // Optimistically, the place we found earlier in the table is still free.
4761 if (firstFree != -1 && bufferSet.iProcAddrTable[firstFree].iProcess != 0)
4763 // If not, we go find another one.
4765 TUint count = bufferSet.iProcAddrTable.Count();
4766 for(TUint i = 0; i < count; ++i)
4768 if (bufferSet.iProcAddrTable[i].iProcess == 0)
4775 // Check if there is a free entry - if so, re-use it.
4776 if (firstFree != -1)
4778 bufferSet.iProcAddrTable[firstFree].iProcess = process;
4779 bufferSet.iProcAddrTable[firstFree].iAddress = baseAddress;
4780 cleanup->SetIndex(firstFree);
4781 NKern::FMSignal(&iLock);
4785 // No free entry. Append it to the list.
4786 NKern::FMSignal(&iLock);
4787 TProcessAddrEntry entry(process, baseAddress);
4788 r = bufferSet.iProcAddrTable.Append(entry);
4791 Kern::ChunkClose(chunk);
4792 NKern::ThreadLeaveCS();
4795 // We added it at the end - so we start from the back and check for the
4796 // process, as some other process COULD have added one after us, so we
4797 // can't just use the count for index!
4799 for(index = bufferSet.iProcAddrTable.Count()-1; index; --index)
4801 if (bufferSet.iProcAddrTable[index].iProcess == process
4802 && bufferSet.iProcAddrTable[index].iAddress != baseAddress)
4807 cleanup->SetIndex(index);
4809 aAddress = reinterpret_cast<TInt>(baseAddress);
4811 NKern::ThreadLeaveCS();
4815 EXPORT_C TInt WinsGui::CurrentConfiguration()
4817 return ::CurrentConfiguration;
4820 GLDEF_C void Fault(TGuiPanic aPanic)
4822 Kern::Fault("WINS-UI",aPanic);
4825 DECLARE_STANDARD_EXTENSION()
4827 __KTRACE_OPT(KEXTENSION,Kern::Printf("Starting Emulator GUI"));
4829 // if NoGui property == true do nothing
4830 if (Property::GetBool("NoGui",EFalse))
4833 // create keyboard driver
4834 TInt r=KErrNoMemory;
4835 masterIni = new DMasterIni;
4838 r = masterIni->Create();
4845 DMultiTouch::iMultiTouchSupported = DMultiTouch::Init();
4847 // Create multitouch when necessary
4848 if (systemIni->MultiTouchEnabled() && systemIni->GCEEnabled() && DMultiTouch::iMultiTouchSupported)
4850 TheMultiTouch = new DMultiTouch(systemIni->MultiTouchProximityStep(),systemIni->MultiTouchPressureStep());
4854 __KTRACE_OPT(KEXTENSION,Kern::Printf("Returns %d",r));
4857 DMultiTouch::iMultiTouchCreated = TRUE;
4860 __KTRACE_OPT(KEXTENSION,Kern::Printf("Returns %d",r));
4864 TInt DWinsUi::DoDefineEmulatorControlHotKey(TAny* aPtr, const char* aValue)
4866 return static_cast<DWinsUi*>(aPtr)->DefineEmulatorControlHotKey(aValue);
4870 TInt DWinsUi::DefineEmulatorControlHotKey(const char* aValue)
4872 const char* beg = skipws(aValue);
4873 const char* end = skiptok(beg);
4874 TInt err = KErrNone;
4876 TEmulCommand command = ENoCommand;
4878 if (_strnicmp(beg, "SelectConfig", end-beg) == 0)
4880 //get the int param which is the config to switch to
4883 data = strtol(beg, &e,0);
4887 command = ESelectConfig;
4889 else if(_strnicmp(beg, "NextConfig", end-beg) == 0)
4891 command = ENextConfig;
4897 if (err != KErrNone)
4901 KeyCombination* pCombination = new KeyCombination(data, command);
4903 return KErrNoMemory;
4907 for (TInt i=0;i<KMaxHotKeyCombinationLength;i++)
4909 TInt key=KErrNotFound;
4910 end2 = skiptok(beg);
4911 TPtrC8 name((const TUint8*)beg, end2-beg);
4912 if ((key=iKeyboard.GetScanCode(name))!=KErrNotFound)
4913 pCombination->AddKey((TStdScanCode)key);
4915 if (beg == end2 || *end2++ != ',')
4919 return iControlHotKeys.Append(pCombination);