Saturday, August 14, 2010

Nokia On Screen D-pad - enabling and disabling

Interestingly, I decided to develop an application on my Nokia phone. This is a touch phone and its for the first time I was trying to develop an application. The application was simple and it has a splashscreen to start with. I tried on the WTK and loaded the application onto the phone. Interestingly, on launching the application, it started to display a Game D pad and Game action keys and my application was getting displayed only around half of the screen. I wanted to take a screenshot of this but neither my Nokia PC suite had this facility nor I tried to search for a utility for doing this.
I tried to search in forums and find out the reason for this and avoid this. My search ended with Nokia developer forum and it has good collection of explanation of why this happens and ways to avoid this. These eventually turned to be a setting which need to be specified in the MIDlet jad file. The setting was with the key ‘Nokia-MIDlet-On-Screen-Keypad’. The following are the possible values for this property.

Nokia-MIDlet-On-Screen-Keypad: no
Nokia-MIDlet-On-Screen-Keypad: gameactions
Nokia-MIDlet-On-Screen-Keypad: navigationkeys

I made the setting to take the value ‘no’ and it served my purpose. My application started displaying the splashscreen without onscreen D-pad and gameactions. Interesting!

Sunday, February 7, 2010

Event Passing Between Brew apps

Thought to delve little more deeper into the event passing mechanism in Brew. In Brew SDK 1.1, there is one brew ishell usage example.

This app is having two class Id.
AEECLSID_SHELL_MAIN_APP - Main application class Id
AEECLSID_SHELL_SUPPORT_APP - Support application class id

The application sends events from AEECLSID_SHELL_MAIN_APP to AEECLSID_SHELL_SUPPORT_APP

the excerpt is given below.

ISHELL_SendEvent (pMe->a.m_pIShell, AEECLSID_SHELL_SUPPORT_APP,
EVT_USER, SEND_EVENT_16BITDATA, COMMON_32BIT_EVENT_DATA);

The following are the definitions of the constants in the above functions.

#define SEND_EVENT_16BITDATA 0
#define POST_EVENT_16BITDATA 1
#define HANDLE_EVENT_16BITDATA 2
#define COMMON_32BIT_EVENT_DATA 0

For testing purpose, altered the above data as

#define SEND_EVENT_16BITDATA 0
#define POST_EVENT_16BITDATA 1
#define COMMON_32BIT_EVENT_DATA "This is a sample data 32 bit"

and the receiving end, the loop is printed as

case EVT_USER:
{
switch (wParam)
{
case SEND_EVENT_16BITDATA:
DBGPRINTF("======= The Event Received in SendEvent is %s",dwParam);
ISHELL_StartApplet(pMe->a.m_pIShell,AEECLSID_SHELL_SUPPORT_APP);
return TRUE;
case POST_EVENT_16BITDATA:
DBGPRINTF("======= The Event Received in PostEvent is %s",dwParam);
ISHELL_StartApplet(pMe->a.m_pIShell,AEECLSID_SHELL_SUPPORT_APP);
return TRUE;
}
}

There is another event passing mechanism introduced in Brew 3.1 is ISHELL_SendURL and ISHELL_PostURL.

ISHELL_SendURL() posts asynchronous event EVT_APP_POST_URL to the applet associated with the URL scheme. The following are the signatures of the app.

boolean ISHELL_PostURL(IShell *po, const char * pszURL);
boolean ISHELL_SendURL(IShell *po, const char * pszURL);

A somewhat nice reference for this is available at the pdf




Monday, January 11, 2010

BREW Display Rendering - IBitmap Faster way?


I was trying to build a user interface which works faster on Touch devices. Unlike the Non touch devices, the display need to be comparatively faster to have a good user experience.

Following is the interface i was planning to be tested for Various options. The application is a Quiz application which presents user with a set of images and user can guess the identity of the image such as name. On Tapping the screen would show the identity of the image with a semi transparency layer background on top of the current image. When the user swipe his finger through the screen, the application would start moving the next image to the display while the current image goes off the display. This transition needed to be smooth.

Given below is the screen shots of this effect. The Quiz app presents a set of country flags.


Following are the items i thought to try.

  • Using IBitmap
  • Directly paint on the screen without using IBitmap
Using IBitmap the following was the one in plan.
- Create a IBitmap of double the screen width and same Screen height.
- When displaying image 1, draw its contents to the first half of the IBitmap
- When the user start swiping the screen, draw the second image to the second half of the IBitmap.
- When the moving happens, Bitblt the IBitmap to the Device bitmap so that it get rendered to the screen.

The above is converted to the following.
if(IDisplay_GetDeviceBitmap(pMe->a.m_pIDisplay,(IBitmap**)&pMe->m_pIBitMap) == SUCCESS)
{
//Got the Device bitmap successfully
IBitmap_GetInfo(pMe->m_pIBitMap,&bmInfo,sizeof(AEEBitmapInfo));
if(IBitmap_CreateCompatibleBitmap(pMe->m_pIBitMap,(IBitmap**)&pMe->m_pIBitMap2,bmInfo.cx *2,bmInfo.cy) == SUCCESS)
{
//Compatible Bitmap2 is created
}
else
{
//Compatible Bitmap Creation failed.
}
}
else
{
//Getting the Device bit map failed
}

The following function fills the first half of the IBitmap

static void QuizApp_PaintScreen(QuizAppStruct *pMe)
{
DBGPRINTF("[QuizApp_PaintScreen] Entering");
// check the app mode here and draw the screen accordingly.
if(pMe->m_pIBitMap != NULL && pMe->m_pIBitMap2 != NULL )
{
DBGPRINTF("[QuizApp_PaintScreen] Destination is set to NULL");
IDisplay_SetDestination(pMe->a.m_pIDisplay,pMe->m_pIBitMap2);
}
QuizApp_PaintQuizImage(pMe);
if(pMe->m_pIBitMap != NULL && pMe->m_pIBitMap2 != NULL )
{
IDisplay_SetDestination(pMe->a.m_pIDisplay,NULL);
IBitmap_BltIn(pMe->m_pIBitMap,0,0,pMe->m_DeviceInfo.cxScreen,pMe->m_DeviceInfo.cyScreen,pMe->m_pIBitMap2,0,0,AEE_RO_TRANSPARENT);
}
IDISPLAY_Update(pMe->m_pIDisplay);
}

The following function is where the second half of the Bitmap buffer is filled. This happens when there is a swipe detected. In this case, Moving left.

boolean QuizApp_OnMovingLeft(void *pi, AEEEvent eCode, uint16 wParam, uint32 dwParam)
{
IImage* pImg;
AEEImageInfo imgInfo;
QuizAppStruct *pMe = (QuizAppStruct*)pi;
DBGPRINTF("[QuizApp_OnMovingLeft] == On Moving Right == ");
if(pMe->m_MovingFirstTime == TRUE)
{
DBGPRINTF("[QuizApp_OnMovingLeft] == On Moving Right FIRST time == ");
pMe->m_MovingFirstTime = FALSE;
pMe->m_ImgIdx ++ ;
if(pMe->m_ImgIdx > pMe->m_TotalImages)
{
pMe->m_ImgIdx = 0;
}
pImg = ISHELL_LoadImage(pMe->a.m_pIShell,pMe->m_ImgPaths[pMe->m_ImgIdx]);
DBGPRINTF("[QuizApp_OnMovingLeft] Img path is %s",pMe->m_ImgPaths[pMe->m_ImgIdx]);
if(pImg != NULL)
{
IImage_GetInfo(pImg,&imgInfo);
pMe->m_ImgDrawRect.x = (pMe->m_DeviceInfo.cxScreen/2)- (imgInfo.cx/2);
pMe->m_ImgDrawRect.y = (pMe->m_DeviceInfo.cyScreen/2)- (imgInfo.cy/2);
IDisplay_SetDestination(pMe->a.m_pIDisplay,pMe->m_pIBitMap2);
IImage_Draw(pImg,pMe->m_DeviceInfo.cxScreen + pMe->m_ImgDrawRect.x,pMe->m_ImgDrawRect.y);
IImage_Release(pImg);
}
pMe->m_dx = 0;

}
else
{
DBGPRINTF("[QuizApp_OnMovingLeft] == On Moving Right NOT FIRST time == ");
pMe->m_dx+= 10;
}
QuizApp_PaintScreenAnimated(pMe);
}

PaintScreenAnimated function paints the contents on to the buffer to the screen without having worries to repaint with all the logic.

static void QuizApp_PaintScreenAnimated(QuizAppStruct *pMe)
{
DBGPRINTF("[QuizApp_PaintScreenAnimated] Entering");
if(pMe->m_pIBitMap != NULL && pMe->m_pIBitMap2 != NULL )
{
DBGPRINTF("[QuizApp_PaintScreenAnimated] Destination is set to NULL");
IDisplay_SetDestination(pMe->a.m_pIDisplay,pMe->m_pIBitMap2);
}
if(pMe->m_pIBitMap != NULL && pMe->m_pIBitMap2 != NULL )
{
IDisplay_SetDestination(pMe->a.m_pIDisplay,NULL);
DBGPRINTF("[QuizApp_PaintScreenAnimated] = dx val is %d",pMe->m_dx);
IBitmap_BltIn(pMe->m_pIBitMap,0,0,pMe->m_DeviceInfo.cxScreen,pMe->m_DeviceInfo.cyScreen,pMe->m_pIBitMap2,pMe->m_dx,0,AEE_RO_TRANSPARENT);
}
IDISPLAY_Update(pMe->m_pIDisplay);
}

This I felt to be not having problems and was working well without much flickering or no flickering.