Mobile SDK for Windows Apps2.0
Transforming Windows apps into Mobile apps
native/orientation/orientation.cpp
// C++ Orientation example using Citrix Mobility Pack SDK
//
// Uses Citrix Mobility Pack SDK to display and change orientation
//
// Copyright (c) 2012 Citrix Systems
//

#include <stdio.h>
#include <windows.h>

#include <cmp.h>

// structures, macros, and data to support converting an orientation number into a name
typedef struct
{
    CMP_ORIENTATION_POSITION    orientation;
    LPCSTR                      name;
} ORIENTATION_NAME, *PORIENTATION_NAME;

#define OrientationToName(x) { x, #x}
#define OrientationEndList() { CMP_ORIENTATION_UNKNOWN, NULL}

ORIENTATION_NAME orientationNames[] = 
{ 
    OrientationToName(CMP_ORIENTATION_UNKNOWN),
    OrientationToName(CMP_ORIENTATION_PORTRAIT),
    OrientationToName(CMP_ORIENTATION_PORTRAIT_UPSIDE_DOWN),
    OrientationToName(CMP_ORIENTATION_LANDSCAPE_LEFT),
    OrientationToName(CMP_ORIENTATION_LANDSCAPE_RIGHT),
    OrientationEndList()
};

// Local functions
void        ReportOrientation(LPCSTR prefix, CMP_ORIENTATION_DATA& orientationData);
LPCSTR      GetOrientationName(CMP_ORIENTATION_POSITION orientation);
void        ReportStatus(LPCSTR text, CMPRESULT rc);
void        WaitForCMPEvents(int seconds);
CMPRESULT   RegisterForEvent(HANDLE hCMP);
CMPRESULT   GetOrientation(HANDLE hCMP, CMP_ORIENTATION_DATA& orientation);
CMPRESULT   SetOrientation(HANDLE hCMP, CMP_ORIENTATION_POSITION position, UINT16 flags);

//
// main entry point for simple orientation program
//
int __cdecl main(int argc, char **argv)
{
    CMPRESULT rc;
    HANDLE hCMP = NULL;

    // initialize for STA (Single Thread Apartment) in COM
    rc = CMPInitialize(FALSE);

    ReportStatus("CMPInitialize", rc);

    // Open a handle to the mobile device
    rc = CMPOpen(&hCMP);

    ReportStatus("CMPOpen", rc);

    if(CMP_SUCCESS(rc))
    {
        // open the link between the two sides
        rc = CMPOpenSession(hCMP);

        ReportStatus("CMPOpenSession", rc);

        if(CMP_SUCCESS(rc))
        {
            CMP_ORIENTATION_DATA orientationData;

            memset(&orientationData, 0, sizeof(orientationData));

            // register for OrientationChanged event
            rc = RegisterForEvent(hCMP);

            // get the orientation data
            rc = GetOrientation(hCMP, orientationData);

            if(CMP_SUCCESS(rc))
            {
                ReportOrientation("\nCMPGetOrientation\n", orientationData);
            }

            printf("\nRotate the device to test the orientation changed event\n");

            // let events come in over the next 15 seconds
            // if this was a Windows program and we had a message loop, we would not need to do this
            WaitForCMPEvents(15);

            // Now lock the orientation to LANDSCAPE_LEFT
            rc = SetOrientation(hCMP, CMP_ORIENTATION_LANDSCAPE_LEFT, CMP_ORIENTATION_FLAG_LOCK);

            printf("Locked the orientation to LANDSCAPE_LEFT\n");

            ReportStatus("CMPSetOrientation", rc);

            printf("Verifying orientation changed to LANDSCAPE_LEFT\n");

            rc = GetOrientation(hCMP, orientationData);

            if(CMP_SUCCESS(rc))
            {
                ReportOrientation("\nCMPGetOrientation\n", orientationData);
            }

            printf("\nRotate the device to test that the application orientation locked\n");

            // let events come in over the next 15 seconds
            WaitForCMPEvents(15);

            // unlock the orientation
            printf("\nOrientation being unlocked to follow the device orientation\n");

            rc = SetOrientation(hCMP, CMP_ORIENTATION_LANDSCAPE_LEFT, CMP_ORIENTATION_FLAG_FOLLOW_SENSOR);

            // close our connection
            CMPCloseSession(hCMP);
        }

        // release our handle
        CMPClose(hCMP);
    }

    // uninitialize COM
    CMPUninitialize();

}

//
// Prints the orientation data (the status of the device's orientation)
//
void ReportOrientation(LPCSTR prefix, CMP_ORIENTATION_DATA& orientationData)
{
    UINT16 flags = orientationData.OrientationFlags;
    CMP_ORIENTATION_POSITION deviceOrientation = (CMP_ORIENTATION_POSITION)orientationData.DeviceOrientation;
    CMP_ORIENTATION_POSITION appOrientation    = (CMP_ORIENTATION_POSITION)orientationData.AppOrientation;

    if(prefix != NULL)
    {
        printf(prefix);
    }

    printf("DeviceOrientation(%s)\n",       GetOrientationName(deviceOrientation));
    printf("AppOrientation(%s)\n",          GetOrientationName(appOrientation));
    printf("Flags(0x%X)",                   flags);

    if(flags & CMP_ORIENTATION_FLAG_LOCK)
    {
        printf(" CMP_ORIENTATION_FLAG_LOCK");
    }

    if(flags & CMP_ORIENTATION_FLAG_FOLLOW_SENSOR)
    {
        printf(" CMP_ORIENTATION_FLAG_FOLLOW_SENSOR");
    }

    printf("\n");
}

//
// Convert orientation to name (string)
//
LPCSTR GetOrientationName(CMP_ORIENTATION_POSITION orientation)
{
    LPCSTR name = NULL;
    PORIENTATION_NAME list = orientationNames;

    while(list->name != NULL)
    {
        if(list->orientation == orientation)
        {
            name = list->name;
            break;
        }

        list++;
    }

    return(name);
}

void ReportStatus(LPCSTR text, CMPRESULT rc)
{
    // only print if something went wrong
    if(CMP_FAILURE(rc))
    {
        printf("%s CMPResult(%08X)\n", text, rc);
    }

    return;
}

//
// A "wait" method which allows events to occur
//
void WaitForCMPEvents(int seconds)
{
    for(int i=0; i<seconds; i++)
    {
        Sleep(1000);
    }
}

// <summary>
// OrientationChanged event handler.
// </summary>
// <param name="hCMP">CMP handler.</param>
// <param name="rc">Return code.</param>
// <param name="DeviceOrientation">Device's orientation.</param>
// <param name="AppOrientation">Application's orientation.</param>
// <param name="OrientationFlags">Orientation flags.</param>
void CMPAPI OrientationChanged(
        HANDLE hCMP, 
        CMPRESULT rc, 
        CMP_ORIENTATION_POSITION DeviceOrientation, 
        CMP_ORIENTATION_POSITION AppOrientation,
        UINT16 OrientationFlags)
{
    CMP_ORIENTATION_DATA orientationData;

    orientationData.DeviceOrientation = DeviceOrientation;
    orientationData.AppOrientation    = AppOrientation;
    orientationData.OrientationFlags  = OrientationFlags;

    ReportOrientation("\nOrientationChanged event\n", orientationData);
}


// <summary>
// Register for the orientation changed event
// </summary>
CMPRESULT RegisterForEvent(HANDLE hCMP)
{
    CMPRESULT rc;

    // Subscribe to OrientationChanged event.
    rc = CMPRegisterForEvent(hCMP, CMP_EVENT_ORIENTATION_CHANGED, (CMP_EVENT_CALLBACK)OrientationChanged); 

    ReportStatus("CMPRegisterForEvent CMP_EVENT_ORIENTATION_CHANGED", rc);

    return(rc);
}

// <summary>
// Get the current orientation
// </summary>
CMPRESULT GetOrientation(HANDLE hCMP, CMP_ORIENTATION_DATA& orientation)
{
    CMPRESULT rc;

    // Gets the orientation data of the device.
    rc = CMPGetOrientation(hCMP, &orientation);

    ReportStatus("CMPGetOrientation", rc);

    return(rc);
}

// <summary>
// Set the application orientation
// </summary>
CMPRESULT SetOrientation(HANDLE hCMP, CMP_ORIENTATION_POSITION position, UINT16 flags)
{
    CMPRESULT rc;

    // Sets the orientation of the app.
    rc = CMPSetOrientation(hCMP, position, flags);

    return(rc);
}
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Events Defines