Using the keyboard

The platform services library of the Native SDK is called bps and it provides an API to basic features of the BlackBerry PlayBook. This includes useful things such as the virtual keyboard, screen, and accelerometer. We'll use the bps library to set up the virtual keyboard.

First, the application must have code to start dispatching keyboard events so that it knows when someone presses a key. This is done in main.c, before the for loop to process events:

virtualkeyboard_request_events(0);
After this, add code to pop up the virtual keyboard on the screen:
virtualkeyboard_show();

To use any virtual keyboard function, you'll need to include the appropriate header file at the beginning of main.c:

#include <bps/virtualkeyboard.h>

Handling keyboard input

Once the virtual keyboard is displayed on the screen, the application can do different things based on what keys are pressed. This involves three steps:

  1. Capturing the fact that something happened on the screen.
  2. Determining that it was a keyboard event.
  3. Performing some action based on the specific key.

Luckily, the project template provides you the code to detect events, in main.c, so we'll just show it here:

while (!exit_application) {
    //Request and process all available BPS events
    bps_event_t *event = NULL;

    for(;;) {
        rc = bps_get_event(&event, 0);
        assert(rc == BPS_SUCCESS);

        if (event) {
           int domain = bps_event_get_domain(event);

            if (domain == screen_get_domain()) {
                handleScreenEvent(event);
            } else if ((domain == navigator_get_domain())
                    && (NAVIGATOR_EXIT == bps_event_get_code(event))) {
                exit_application = 1;
            }
        } else {
            break;
        }
    }
    render();
}
This event processing loop runs until the NAVIGATOR_EXIT event occurs (when a user closes the application from the navigator). Otherwise, when a user performs an action on the screen such as touch, swipe, or release, this loop calls the handleScreenEvent() function.

The handleScreenEvent() function already exists in the template, so all we do is add another case to the switch statement to get the type of keyboard event that occurred. The new case handles the event of a downward key press on the virtual keyboard.

case SCREEN_EVENT_KEYBOARD:
  screen_get_event_property_iv(screen_event, SCREEN_PROPERTY_KEY_FLAGS, &screen_val);

  if (screen_val & KEY_DOWN) {
From there, we get the specific key press and perform the desired action. In this case, we can change the layout of the keyboard so that it's more suited to some function the user wants to perform, such as sending an email or entering a phone number.
screen_get_event_property_iv(screen_event, SCREEN_PROPERTY_KEY_FLAGS, &screen_val);

		if (screen_val & KEY_DOWN) {
			screen_get_event_property_iv(screen_event, SCREEN_PROPERTY_KEY_SYM,&screen_val);

			printf("The '%c' key was pressed\n", (char)screen_val);
			fflush(stdout);

			switch (screen_val) {
			case KEYCODE_I:
				// Display the email layout with "Send" enter key
				virtualkeyboard_change_options(VIRTUALKEYBOARD_LAYOUT_EMAIL, VIRTUALKEYBOARD_ENTER_SEND);
				break;
			case KEYCODE_O:
				// Display the phone layout with "Connect" enter key
				virtualkeyboard_change_options(VIRTUALKEYBOARD_LAYOUT_PHONE, VIRTUALKEYBOARD_ENTER_CONNECT);
				break;
			case KEYCODE_P:
				// Display the default layout with default enter key
				virtualkeyboard_change_options(VIRTUALKEYBOARD_LAYOUT_DEFAULT, VIRTUALKEYBOARD_ENTER_DEFAULT);
				break;

On the screen, the layouts would look like this:

Diagram showing the default, phone, and email keyboard layouts.

You'll notice that there is a printf() and a fflush() statement in the code above. These are used to send the keyboard character that was pressed out to the console, in case you want to debug the application later.

We can also hide the virtual keyboard, which is useful when you want to use the full screen to display something. The user can pop up the virtual keyboard again by swiping from the bottom left of the bezel towards the center of the screen.

case KEYCODE_H:
				// Hide the keyboard
				virtualkeyboard_hide();
				break;

Change the behavior of your application

We can try something a little more complicated by changing the behavior of the project template. If you've run the application already, you would have seen a colored square rotating slowly on the screen. In the code below, we'll vary the speed of the square.

First, in main.c, we declare a variable to specify the rotation angle of the square and some constants to define how the behavior will change.

#define ANGLE_INCREMENT 3.0f
#define CIRCLE_DEGREES 360.0f
static float angle = 0.0;
Next, we build on the switch statement in handleScreenEvent() to increment or decrement the angle when a user presses the a or z key.
case KEYCODE_A:
  // Increment rotation angle
  angle = fmod(angle + ANGLE_INCREMENT, CIRCLE_DEGREES );
  break;
case KEYCODE_Z:
  // Decrement rotation angle
  angle = fmod(angle - ANGLE_INCREMENT, CIRCLE_DEGREES );
  break;
The main application loop calls the existing render() function on a periodic basis to update the display. We'll modify this function slightly to change the angle of rotation by replacing the fixed angle with our new angle variable.
glRotatef(angle, 0.0f, 1.0f, 0.0f);

That's it! You can now build and run your application. Try playing with the keyboard to see how the application changes or changing the keyboard handler to map different functions to different keys.