Last month, we introduced the BREW platform and discussed how to set up the SDK, and use the Application Wizard to create a basic skeletal source file. This month, we delve deeper into the source and see the meaning of each line of the code and extend the capabilities to do things such as write text, draw images and take user input. We assume you are already familiar with the C syntax, and have read Part I of this series.
The source
Here is the basic source of the 'HelloWorld' application that comes bundled with the application.
/*===============================================================================
INCLUDES AND VARIABLE DEFINITIONS
=============================================================================== */
1- #include "AEEAppGen.h" // Applet helper file
2- #include "helloworld.bid" // Applet-specific header that contains class ID
/*-------------------------------------------------------------------
Static function prototypes
-------------------------------------------------------------------*/
3- static boolean HelloWorld_HandleEvent(AEEApplet * pme, AEEEvent eCode,uint16 wParam, uint32 dwParam);
/*===============================================================================
FUNCTION DEFINITIONS
=============================================================================== */
4- int AEEClsCreateInstance(AEECLSID ClsId,IShell * pIShell,IModule * pMod,void ** ppObj)
5- {
6- *ppObj = NULL;
7- if(AEEApplet_New( sizeof(AEEApplet), // Size of our private class
ClsId, // Our class ID
pIShell, // Shell interface
pMod, // Module instance
(IApplet**)ppObj, // Return object
(AEEHANDLER)HelloWorld_HandleEvent, // Our event handler
NULL)) // No special "cleanup" function
8- return(AEE_SUCCESS);
9- return (EFAILED);
10- }
11- static boolean HelloWorld_HandleEvent(AEEApplet * pMe, AEEEvent eCode, uint16 wParam, uint32 dwParam)
12- {
13- AECHAR szText<> = {'H','e','l','l','o',' ','W','o', 'r', 'l', 'd', '\0'};
14- switch (eCode){
15- case EVT_APP_START:
16- IDISPLAY_DrawText(pMe->m_pIDisplay, // Display instance
AEE_FONT_BOLD, // Use BOLD font
szText, // Text - Normally comes from resource
-1, // -1 = Use full string length
0, // Ignored - IDF_ALIGN_CENTER
0, // Ignored - IDF_ALIGN_MIDDLE
NULL, // No clipping
IDF_ALIGN_CENTER | IDF_ALIGN_MIDDLE);
17- IDISPLAY_Update (pMe->m_pIDisplay);
18- return(TRUE);
19- case EVT_APP_STOP:
20- return(TRUE);
21- default:
22- break;
23- }
24- return(FALSE);
25- }
|
Small as this code is, it gives some important insights on the way BREW works, and how you can extend its functionality. Let's start from the beginning.
Lines 1 and 2: The first file, AEEAppGen.h, contains the code for certain under-the-hood BREW functions, like those used for creating an application structure. The second file, helloworld.bid¸ is created by the programmer using the MIF editor. This file contains the unique ID that every BREW application must have, as explained in the last article. To create this file, open the MIF editor and click on 'New Applet'. Put in an application name, click on Locally and enter a random eight-digit hex
number. The Locally option lets you run your application for testing purposes.
This function, AEEClsCreateInstance, must be present in all BREW applications. This function is invoked when the application is being loaded, and it must have the same signature as presented in this source. Its primary task, in turn, is to invoke AEEApplet_New. The first four arguments are input for the function (as described in the comments), while the fifth is the application structure, then the event handler and cleanup function.
|
A slight explanation of the application structure is called for. In BREW, you cannot have any global variables, and as such all data that has to be made available to all the different functions of your application must be encapsulated in one structure, called the application structure, and passed between functions.
The structure used in this application is the default, simple one with the bare necessities-a pointer to the shell, module and display, and pointers to two functions-an event handler and a cleanup function that should free all the memory on application shutdown. All this allocation happens in this call to
AEEApplet_New.
Lines 11 to 25: This is our main event handler. BREW is an event-driven platform, and anything that you do on the phone triggers events, which are then passed onto your application for processing. Events include but are not limited to, application startup/shutdown, key presses and phone suspend/resume. In our case, we only handle the startup event
(EVT_APP_START), since we are not handling any key presses or any other condition.
Line 7: This is a call to the IDISPLAY_DrawText function, which is used to draw text to the screen. The first argument is a pointer to the display interface, which gets initialized in our AEEApplet_New function itself. Next are the font, the string to be drawn, number of characters (-1 means the whole string), x and y coordinates, clipping rectangle, and finally the flags that determine other factors on how the text is to be drawn.
Finding help on any of these functions is quite easy, since the SDK comes with a handy API reference document that does an excellent job of explaining all the functions available to the programmer. Some of the other functions that you will find yourself using quite often are IIMAGE_Draw for drawing images, IDISPLAY_DrawRect for drawing rectangles,
IGRAPHICS_DrawLine for drawing lines and IDISPLAY_FillRect for filling rectangles.
Line 17: In almost all cases, any calls to BREW functions that draw on the screen will not actually update the screen itself. The changes get committed to memory, and are reflected on the display only after a call to
IDISPLAY_Update.
Hopefully by now, this article has given you a better understanding of the BREW platform and how to code for it. There are some basic axioms to follow while coding for BREW- like never to use any of the built-in C libraries and instead rely on the API provided by Qualcomm-but otherwise getting comfortable with the platform is simply all about knowing the API and its capabilities and limitations. While this article only touched over some basic programming, we'll introduce advanced topics in our forthcoming articles.
Anuj Jain