This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Display rotation query by ChangeDisplaySettingsEx()

Hi,

I rotate the display by 90 degrees by setting "Angle" to 1 in dss.reg and it is fine.  However, I have an external touch monitor that could not detect this rotation.  To look into this issue, I ran the Xaml application "Bounce.xaml" and found out that XamlPerf.exe in BSP ARM_A8_01_01 also could not detect the rotation - the function call "ChangeDisplaySettingsEx(NULL, &DevMode, NULL, CDS_TEST, NULL)" in the file main.c of XAMLPERF always return DMDO_0 even though my display is rotated by 90 degrees.

Can you tell if it is a WinCE or BSP problem?  I appreciate your help.

Luan

  • I dont recall any such issue - in fact we have the "do rotate" command which uses similar code. In your setup with Angle set to 1 in registry, can you use "do rotate" command  (no parameter) from telnet window and see if the display changes to 180.

    -Madhvi

  • Hi Madhvi,

    I probably did not make my question clear.  The problem is not the rotation but the query of the rotation by the application such as XamlPerf.  The following piece of code comes from main.c of the XamlPerl application:

        if(Height > Width && g_VRFB)
        {       
            DEVMODE DevMode;
            memset(&DevMode, 0, sizeof (DevMode));
            DevMode.dmSize               = sizeof (DevMode);
            DevMode.dmFields             = DM_DISPLAYORIENTATION;
           
            if (DISP_CHANGE_SUCCESSFUL != ChangeDisplaySettingsEx(NULL, &DevMode, NULL, CDS_TEST, NULL))
            {
                RETAILMSG(1, (L"ChangeDisplaySettingsEx failed to get the supported rotation angles (error=%d).\n", GetLastError()));
            }
            else
            {
                if(DevMode.dmDisplayOrientation == 0)                                        // if display is not rotated
                {   
                    DevMode.dmDisplayOrientation = DMDO_90;                         // rotate it by 90 degrees
                    if (ChangeDisplaySettingsEx(NULL, &DevMode, NULL, CDS_RESET, NULL) != DISP_CHANGE_SUCCESSFUL)
                    {
                        RETAILMSG(1, (L"ChangeDisplaySettingsEx failed to change the rotation angle (error=%d).\r\n", GetLastError()));
                    }
                    else
                    {
                        g_bRotation = TRUE;
                        WindowParameters.Height      = Width;
                        WindowParameters.Width       = Height;
                        g_FRM.m_DisplayWidth = Height;
                        g_FRM.m_DisplayHeight = Width;
                    }
                }
            }
        }

    In the above, the first call of ChangeDisplaySettingsEx(NULL, &DevMode, NULL, CDS_TEST, NULL) returns 0 in DevMode.dmDisplayOrientation, which causes an additional 90-degree rotation by the following code.  When I run "XamlPerf Bounce.xaml", I can see that XamlPerf rotates my display for another 90 degrees for a total of 180 degrees.

    My question is why my display is rotated by 90 degrees but when an application queries this information by calling ChangeDisplaySettingsEx(NULL, &DevMode, NULL, CDS_TEST, NULL), the return value in DevMode.dmDisplayOrientation is DMDO_0 instead of DMDO_90.  What could cause this problem, WinCE or BSP?

    Thanks,

    Luan

     

  • I understand your question now. This behavior is partly due to WinCE and partly BSP. See note in omap_ddgpe.cpp for DRVESC_GETSCREENROTATION. When we return the value back to OS, we subtract the initial angle from the actual rotation value. This is because in OMAP, the display h/w and not the kernel handles the rotation. The code in XAMLPerf should not assume that 0 degree is portrait mode. In fact, it should use the width and height ratio to determine portrait and landscape mode and then accordingly rotate the display.

     

    case DRVESC_GETSCREENROTATION:
                //  Only if the surface manager supports rotation
                if( m_pSurfaceMgr->SupportsRotation() == TRUE )
                {
                    /* Since WinCE always considers the boot-up width and height to be 0 degree orientation,
                       we need to manipulate the m_iGraphicsRotate rotation angle when the device has booted up in 90,180 or 270
                       orientation (specified through registry setting and stored in g_Globals.m_dwRotationAngle) */


                //  Get state of graphics plane rotation
                    DWORD graphicsRotate = getOrientation((getAngle(m_iGraphicsRotate)-getAngle(g_Globals.m_dwRotationAngle)+360)%360);
                    *(int *)pvOut = ((DMDO_0 | DMDO_90 | DMDO_180 | DMDO_270) << 8) | ((BYTE)graphicsRotate);
                rc = DISP_CHANGE_SUCCESSFUL;
                }
                break;

     

     

  • Hi Madhvi,

    Thanks very much for the explanation.

    My original problem is not XamlPerf but an external touch monitor whose driver behaves in the same way as XamlPerf.  To work around this issue, I am not sure if I could modify omap_ddgpe.cpp so that it returns the value corresponding to the actual rotated angles.  I am afraid that there might be some side effect for doing so.

    Do you have a suggestion for me to resolve this issue?

    Thanks,

    Luan

  • if you dont mind, can you explain a little more about your touch monitor - what action does it take based on rotation angle?

    You cannot change the DRVESC_GETSCREENROTATION/DRVESC_SETSCREENROTATION else the rotation will break. If you dont mind a custom solution, then you could implement a custom DRVESC in display driver for retrieving the actual rotation angle. From your touch monitor, you could then call this custom DRVESC to get the actual rotation angle - see DRVESC_TVOUT_ENABLE as an example and how its called from shell.cxx.

    -Madhvi

     

  • Hi Madhvi,

    We have a VGA output on our target for the capacitive touch monitor.  When I do not rotate the display, the touch monitor works correctly without any calibration.  Actually, the vendor said that there is no calibration required for capacitive touch.  When I rotate the display by 90, the touch position is now detected 90 degrees back in counter clockwise direction.  For instance, if I touch the upper right corner, my mouse cursor will point at the upper left corner; similarly, if I touch the lower right corner, the touch monitor will point at the upper right corner.

    The people who wrote the driver for the touch monitor said that they use Microsoft SDK function "ChangeDisplaySettingsEx" to get the rotation information.  They sent me a snippet of their driver's code as below:

    devMode.dmFields = DM_DISPLAYORIENTATION;   
      if (ChangeDisplaySettingsEx(NULL,&devMode,NULL,CDS_TEST,NULL) == DISP_CHANGE_SUCCESSFUL)
     {
      switch( devMode.dmDisplayOrientation )
      {
      case DMDO_90:
             ...
             break;
      case DMDO_180:
            ...
             break;
      case DMDO_270:
           ...
             break;
      default:
             break;
      }

    As I said, it is the same way as XamlPerf's to find out the rotation.  I doubt that they would change their driver, using screen Width and Height to determine rotation, just for us.  That is the reason I ask you for your idea about a workaround.  By the way, if you use Width and Height, how can you know if the screen has been rotated by 90 or 270.

    Thanks,

    Luan

  • So instead of using Angle=1 for 90 degree rotation, you could do something what "do rotate 90" command does from an app or from display driver itself. What this means is that your g_Globals.m_dwRotationAngle will be 0 (because Angle=0) and then GWES system will use DRVESC_SETSCREENROTATION to rotate to 90. This way DRVESC_GETSCREENROTATION will return 90. However you will have to do this rotation before touch monitor driver comes up. In short, instead of using static rotation (using Angle field), you will be doing dynamic rotation using ChangeDisplaySettingsEx(CDS_RESET). Hope this helps.

    Regarding width and height, you can only determine whether you are in landscape or portrait mode and not the rotation angle. I dont think that solution would apply to your case - in touch monitor, you need to know the actual rotation.

    -Madhvi


     

  • Hi Madhvi,

    That is a good idea.  After setting the registry for no rotation, I added the code below in my startup app and the touch monitor is happy.  However, when I put it at the end of OMAPDDGPE::OMAPDDGPE(), the bootup hangs.  Maybe it is too early to do this.  I would like to do this in the BSP instead of the application, so I have to find a good place in the driver to do this.

     

     

     

    DEVMODE DevMode;
    memset(&DevMode, 0, sizeof (DevMode));
    DevMode.dmSize               = sizeof (DevMode);     
    DevMode.dmFields             = DM_DISPLAYORIENTATION;
    DevMode.dmDisplayOrientation = DMDO_90;

    if (DISP_CHANGE_SUCCESSFUL != ChangeDisplaySettingsEx(NULL, &DevMode, NULL, CDS_RESET, NULL))
    {
        RETAILMSG(1, (L"ChangeDisplaySettingsEx failed to set rotation angles (error=%d).\n", GetLastError()));
    }

    By the way, Do you think this approach will have any impact on the graphic performance?  OurGUI guy was asking for better graphic performance.

    Thanks,

    Luan

  • With any amount of rotation (except for 0 degrees), whether at boot up or dynamic, there is some performance impact. Also, it does depend on the display size as well.

    Check if SetMode() is a better place to do your rotation - I am not sure how often this is called though.

    -Madhvi