void BPSEventListener::event(bps_event_t *event) {
    if (event != NULL) {
        if (bps_event_get_domain(event) == virtualkeyboard_get_domain()) {
            uint16_t code = bps_event_get_code(event);
            if (code == VIRTUALKEYBOARD_EVENT_VISIBLE) {
                int pixelsHeight = 0;
                virtualkeyboard_get_height(&pixelsHeight);
                if (pixelsHeight > _mPixelsHeightToConsiderKeyboardVisible) {
                    _isKeyboardVisible = true;
                    emit keyboardVisibilityUpdated();
                }
            } else if (code == VIRTUALKEYBOARD_EVENT_HIDDEN && _isKeyboardVisible) {
                _isKeyboardVisible = false;
                emit keyboardVisibilityUpdated();
            } else if (code == VIRTUALKEYBOARD_EVENT_INFO) {
                int pixelsHeight = 0;
                virtualkeyboard_get_height(&pixelsHeight);
                _isKeyboardVisible = pixelsHeight > _mPixelsHeightToConsiderKeyboardVisible;
                emit keyboardVisibilityUpdated();
            }
        } else if (bps_event_get_domain(event) == netstatus_get_domain()) {
            if (NETSTATUS_INFO == bps_event_get_code(event)) {
                netstatus_info_t *info = netstatus_event_get_info(event);
                if (info) {
                    bool networkReachable = netstatus_info_get_availability(info);
                    ms_message("[BB10] Network status event: network reachable: %i", networkReachable);

                    LinphoneManager *manager = LinphoneManager::getInstance();
                    linphone_core_set_network_reachable(manager->getLc(), networkReachable);
                }
            }
        }
    }
}
Ejemplo n.º 2
0
void Keyboard_NDK::event(bps_event_t *event) {
    Json::FastWriter writer;
    Json::Value root;
    root["threadCount"] = "10";
    int domain = bps_event_get_domain(event);
      if (domain == virtualkeyboard_get_domain()) {
          int code = bps_event_get_code(event);
          int a;
          std::string str;
          std::string eventString;
          std::ostringstream strs;
          switch(code) {
              case VIRTUALKEYBOARD_EVENT_VISIBLE:
                  eventString = "native.keyboardshow";
                  eventString.append(" ");
                  virtualkeyboard_get_height(&a) ;
                  strs << a;
                  str = strs.str();
                  eventString.append("{\"keyboardHeight\":\""+str+"\"}");
                  m_pParent->NotifyEvent(eventString);

                  break;
              case VIRTUALKEYBOARD_EVENT_HIDDEN:

                  m_pParent->NotifyEvent("native.keyboardhide");
                  break;
          }
      }

}
QT_BEGIN_NAMESPACE

QQnxVirtualKeyboardBps::QQnxVirtualKeyboardBps(QObject *parent)
    : QQnxAbstractVirtualKeyboard(parent)
{
    if (locale_request_events(0) != BPS_SUCCESS)
        qWarning("QQNX: Failed to register for locale events");

    if (virtualkeyboard_request_events(0) != BPS_SUCCESS)
        qWarning("QQNX: Failed to register for virtual keyboard events");

    int height = 0;
    if (virtualkeyboard_get_height(&height) != BPS_SUCCESS)
        qWarning("QQNX: Failed to get virtual keyboard height");

    setHeight(height);
}
Ejemplo n.º 4
0
bool myEventFilter(void *message) {
	// here we should have all requested bps events (no Qt events here)
    bps_event_t *event = (bps_event_t*)message;
    if (event) {
    	int domain = bps_event_get_domain(event);
    	if (domain == virtualkeyboard_get_domain()) {
    		unsigned int ec = bps_event_get_code(event);
    		 if (!bKBhidden && ec == VIRTUALKEYBOARD_EVENT_INFO){
    			int nNewKBHeight = virtualkeyboard_event_get_height(event);
    			virtualkeyboard_get_height(&nNewKBHeight);
    			if ( nNewKBHeight != nKBHeight){
    				nKBHeight = nNewKBHeight;
    				QRect r = QApplication::desktop()->screenGeometry(0);
    				if (r.width() > 800){
    					// Landscape
    					console->setGeometry(0, 0, r.width()-73, r.height()-nKBHeight);
    				}else{
    					// Portrait - keyboard is taller
    					console->setGeometry(0, 53, r.width(), r.height()-nKBHeight-53);
    				}
    			}
    		}
    		QRect r = QApplication::desktop()->screenGeometry(0);
    		if (ec == VIRTUALKEYBOARD_EVENT_VISIBLE){
				bKBhidden = false;
				nKBHeight = nMaxKBHeight;
				virtualkeyboard_change_options(VIRTUALKEYBOARD_LAYOUT_DEFAULT, VIRTUALKEYBOARD_ENTER_DEFAULT);
    		}else if (ec == VIRTUALKEYBOARD_EVENT_HIDDEN){
				bKBhidden = true;
				nKBHeight = 0;
    		}
			if (r.width() > 800) console->setGeometry(0, 0, r.width()-73, r.height()-nKBHeight); // Landscape
			else console->setGeometry(0, 103, r.width(), r.height()-nKBHeight-103); // Portrait

			//font = QFont(QString("Courier New"), 6);
			font.setPixelSize(mainWindow->nFontSize);
		    font.setStyle(QFont::StyleNormal);
		    font.setWeight(QFont::Normal);
			console->setTerminalFont(font);
    	}
   	}
 	mainEventFilter(message); // Call replaced event filter so we deliever everything to Qt that runs in background
	return false;
}
Ejemplo n.º 5
0
void CCEGLView::showKeyboard()
{
	int height;

	virtualkeyboard_get_height(&height);

	float factor = m_fScaleY / CC_CONTENT_SCALE_FACTOR();
	height = (float)height / factor;

	CCRect rect_begin(0, 0 - height, m_obScreenSize.width / factor, height);
	CCRect rect_end(0, 0, m_obScreenSize.width / factor, height);

    CCIMEKeyboardNotificationInfo info;
    info.begin = rect_begin;
    info.end = rect_end;
    info.duration = 0;

    CCIMEDispatcher::sharedDispatcher()->dispatchKeyboardWillShow(info);
    virtualkeyboard_show();
    CCIMEDispatcher::sharedDispatcher()->dispatchKeyboardDidShow(info);
}
Ejemplo n.º 6
0
int main(int argc, char *argv[])
{
    // Let's search for programs first in our own 'app' folder
    QString oldPath = qgetenv("PATH");
    QString newPath = "app/native:"+oldPath;
    qputenv("PATH", newPath.toAscii().data());

    // We need to store our working folder somewhere, it is needed for ssh later
    int res = system ("echo -n `pwd`\"/data/\" > data/.myhome");
    if (res == -1){
    	fprintf(stderr, "Can't determine my home folder location, terminating");
    	exit(-1);
    }

	// Init file descriptors opening proper devices
	masterFdG = ::open("/dev/ptyp1", O_RDWR);
	slaveFdG = ::open("/dev/ttyp1", O_RDWR | O_NOCTTY);
	// And here is where magic begins
    pidG_ = fork();
    if (pidG_ == 0) {
        dup2(slaveFdG, STDIN_FILENO);
        dup2(slaveFdG, STDOUT_FILENO);
        dup2(slaveFdG, STDERR_FILENO);

        // reset all signal handlers
        struct sigaction act;
        sigemptyset(&act.sa_mask);
        act.sa_handler = SIG_DFL;
        act.sa_flags = 0;
        for (int sig = 1; sig < NSIG; sig++)
          sigaction(sig, &act, 0L);

        // All we want in child process is to have sh running
        const char *arglist[] = {"/bin/sh", "-l", NULL};
        execvp(arglist[0], (char**)arglist);
    } else if (pidG_ == -1) {
        // fork() failed
  	    qDebug() << "fork() failed:";
        pidG_ = 0;
        return false;
    }
    // Drop garbage that is shown when you start the app
    char cGarbage[72];
    read(masterFdG, cGarbage, 72);

    // needed for correct QT initialization
    //qputenv("QT_QPA_FONTDIR", "/usr/fonts/font_repository/dejavu-ttf-2.17"); // needed for correct QT initialization

    qputenv("QT_QPA_PLATFORM_PLUGIN_PATH", "/usr/lib/qt4/plugins/platforms");

    //QCoreApplication::addLibraryPath("app/native/lib"); // blackberry plugin does not load without this line

    QApplication app(argc, argv);

    mainWindow = new CMyMainWindow();
    QRect r = QApplication::desktop()->screenGeometry(0);
    mainWindow->resize(r.width()+1, r.height()+1);

    console = new QTermWidget(1, mainWindow);

    font = QFont(QString("Courier New"), 6);
    font.setPixelSize(mainWindow->nFontSize);
    font.setStyle(QFont::StyleNormal);
    font.setWeight(QFont::Normal);
	console->setTerminalFont(font);

#ifndef BBQ10
    // We start the app with shown keyboard
	virtualkeyboard_change_options(VIRTUALKEYBOARD_LAYOUT_DEFAULT, VIRTUALKEYBOARD_ENTER_DEFAULT);
	if (r.width() > 800){
		// Landscape
		virtualkeyboard_get_height(&nKBHeight);
		console->setGeometry(0, 0, r.width()-73, r.height()-nKBHeight);
	}else{
		// Portrait - keyboard is higher
		virtualkeyboard_get_height(&nKBHeight);
		console->setGeometry(0, 103, r.width()+1, r.height()-nKBHeight-102);
	}
#else
	console->setGeometry(0, 0, r.width()+1, r.height()-103);
#endif
    console->setScrollBarPosition(QTermWidget::ScrollBarRight);

    // Our 'soft buttons' menu
    Menu = new CMyMenu(mainWindow);
    Menu->MenuInit();

    // Our system menu
    SystemMenu = new CMySystemMenu(mainWindow);
    SystemMenu->MenuInit();

    QObject::connect(console, SIGNAL(finished()), mainWindow, SLOT(close()));

    mainWindow->show();    

#ifndef BBQ10
    // Install event filter
    mainEventFilter = QAbstractEventDispatcher::instance()->setEventFilter(myEventFilter);

    // Show virtual keyboard
    QEvent event(QEvent::RequestSoftwareInputPanel);
    QApplication::sendEvent(console, &event);
    virtualkeyboard_get_height(&nMaxKBHeight); // Init maximum VK height

    virtualkeyboard_request_events(0); // To catch show/hide VK events
#endif
#ifdef BBQ10
    virtualKeyboard = new CMyVirtualKeyboard(mainWindow);
#endif
    return app.exec();
}
void fgPlatformProcessSingleEvent ( void )
{
    if(fgStructure.CurrentWindow == NULL) {
        //XXX Is this right? Would this just cause a whole lot of busy looping while we wait for events?
        LOGW("fgPlatformProcessSingleEvent: Missing current window. Skipping event processing");
        return;
    }

    if(fgDisplay.pDisplay.event == NULL)
        /* Nothing to do */
        return;

    int domain;
    do
    {
        SFG_Window* window = fgStructure.CurrentWindow;
#ifdef __PLAYBOOK__
        /* Get the keyboard height before doing anything since we otherwise don't get it until it changes */
        if(window->State.pWState.keyboardHeight == 0) {
            virtualkeyboard_get_height(&window->State.pWState.keyboardHeight);
        }
#endif
        domain = bps_event_get_domain(fgDisplay.pDisplay.event);
        if (domain == screen_get_domain()) {
            int eventType;
            int mod;
            screen_event_t screenEvent = screen_event_get_event(fgDisplay.pDisplay.event);
            screen_get_event_property_iv(screenEvent, SCREEN_PROPERTY_TYPE, &eventType);
            switch (eventType) {

            //Mostly from fg_main_android
            case SCREEN_EVENT_MTOUCH_TOUCH:
            case SCREEN_EVENT_MTOUCH_RELEASE:
            case SCREEN_EVENT_MTOUCH_MOVE:
            {
                mtouch_event_t touchEvent;
                screen_get_mtouch_event(screenEvent, &touchEvent, 0);
#ifndef __PLAYBOOK__
                screen_get_event_property_iv(screenEvent, SCREEN_PROPERTY_KEY_MODIFIERS, &mod);
#else
                mod = 0;
#endif

                LOGI("fgPlatformProcessSingleEvent: SCREEN_EVENT_MTOUCH_*: Type: 0x%X, X: %d, Y: %d, Contact Id: %d, Mod: 0x%X", SLOG2_FA_SIGNED(eventType), SLOG2_FA_SIGNED(touchEvent.x), SLOG2_FA_SIGNED(touchEvent.y), SLOG2_FA_SIGNED(touchEvent.contact_id), SLOG2_FA_SIGNED(mod));

                /* Remember the current modifiers state so user can query it from their callback */
                fgState.Modifiers = fgPlatformGetModifiers(mod);

                if(touchEvent.contact_id == 0) {
                    int size[2];
                    screen_get_window_property_iv(window->Window.Handle, SCREEN_PROPERTY_BUFFER_SIZE, size);
                    handle_left_mouse(touchEvent.x, touchEvent.y, size[1], eventType, window);
                }

                //Now handle mutlitouch (adapted from fg_main_windows)
                if (eventType == SCREEN_EVENT_MTOUCH_TOUCH) {
                    INVOKE_WCB( *window, MultiEntry,  ( touchEvent.contact_id, GLUT_ENTERED ) );
                    INVOKE_WCB( *window, MultiButton, ( touchEvent.contact_id, touchEvent.x, touchEvent.y, 0, GLUT_DOWN ) );
                } else if (eventType == SCREEN_EVENT_MTOUCH_MOVE) {
                    INVOKE_WCB( *window, MultiMotion, ( touchEvent.contact_id, touchEvent.x, touchEvent.y ) );
                    //XXX No motion is performed without contact, thus MultiPassive is never used
                } else if (eventType == SCREEN_EVENT_MTOUCH_RELEASE) {
                    INVOKE_WCB( *window, MultiButton, ( touchEvent.contact_id, touchEvent.x, touchEvent.y, 0, GLUT_UP ) );
                    INVOKE_WCB( *window, MultiEntry,  ( touchEvent.contact_id, GLUT_LEFT ) );
                }

                fgState.Modifiers = INVALID_MODIFIERS;
                break;
            }

            case SCREEN_EVENT_POINTER:
            {
                //Based off/part taken from GamePlay3d PlatformBlackBerry
                static int mouse_pressed = 0;
                int buttons;
                int position[2];
                int wheel;
                // A move event will be fired unless a button state changed.
                bool move = true;
                bool left_move = false;
                // This is a mouse move event, it is applicable to a device with a usb mouse or simulator.
                screen_get_event_property_iv(screenEvent, SCREEN_PROPERTY_BUTTONS, &buttons);
                screen_get_event_property_iv(screenEvent, SCREEN_PROPERTY_SOURCE_POSITION, position);
#ifndef __PLAYBOOK__
                screen_get_event_property_iv(screenEvent, SCREEN_PROPERTY_MOUSE_WHEEL, &wheel);
                screen_get_event_property_iv(screenEvent, SCREEN_PROPERTY_KEY_MODIFIERS, &mod);
#else
                wheel = mod = 0;
#endif
                int size[2];
                screen_get_window_property_iv(window->Window.Handle, SCREEN_PROPERTY_BUFFER_SIZE, size);

                LOGI("fgPlatformProcessSingleEvent: SCREEN_EVENT_POINTER: Buttons: 0x%X, X: %d, Y: %d, Wheel: %d, Mod: 0x%X", SLOG2_FA_SIGNED(buttons), SLOG2_FA_SIGNED(position[0]), SLOG2_FA_SIGNED(position[1]), SLOG2_FA_SIGNED(wheel), SLOG2_FA_SIGNED(mod));

                //XXX Is multitouch be handled in a good way?

                /* Remember the current modifiers state so user can query it from their callback */
                fgState.Modifiers = fgPlatformGetModifiers(mod);

                // Handle left mouse. Interpret as touch if the left mouse event is not consumed.
                if (buttons & SCREEN_LEFT_MOUSE_BUTTON) {
                    if (mouse_pressed & SCREEN_LEFT_MOUSE_BUTTON) {
                        left_move = true;
                    } else {
                        move = false;
                        mouse_pressed |= SCREEN_LEFT_MOUSE_BUTTON;
                        handle_left_mouse(position[0], position[1], size[1], SCREEN_EVENT_MTOUCH_TOUCH, window);
                    }
                } else if (mouse_pressed & SCREEN_LEFT_MOUSE_BUTTON) {
                    move = false;
                    mouse_pressed &= ~SCREEN_LEFT_MOUSE_BUTTON;
                    handle_left_mouse(position[0], position[1], size[1], SCREEN_EVENT_MTOUCH_RELEASE, window);
                }

                // Handle right mouse.
                if (buttons & SCREEN_RIGHT_MOUSE_BUTTON) {
                    if ((mouse_pressed & SCREEN_RIGHT_MOUSE_BUTTON) == 0) {
                        move = false;
                        mouse_pressed |= SCREEN_RIGHT_MOUSE_BUTTON;
                        INVOKE_WCB(*window, Mouse, (GLUT_RIGHT_BUTTON, GLUT_DOWN, position[0], position[1]));
                    }
                } else if (mouse_pressed & SCREEN_RIGHT_MOUSE_BUTTON) {
                    move = false;
                    mouse_pressed &= ~SCREEN_RIGHT_MOUSE_BUTTON;
                    INVOKE_WCB(*window, Mouse, (GLUT_RIGHT_BUTTON, GLUT_UP, position[0], position[1]));
                }

                // Handle middle mouse.
                if (buttons & SCREEN_MIDDLE_MOUSE_BUTTON) {
                    if ((mouse_pressed & SCREEN_MIDDLE_MOUSE_BUTTON) == 0) {
                        move = false;
                        mouse_pressed |= SCREEN_MIDDLE_MOUSE_BUTTON;
                        INVOKE_WCB(*window, Mouse, (GLUT_MIDDLE_BUTTON, GLUT_DOWN, position[0], position[1]));
                    }
                } else if (mouse_pressed & SCREEN_MIDDLE_MOUSE_BUTTON) {
                    move = false;
                    mouse_pressed &= ~SCREEN_MIDDLE_MOUSE_BUTTON;
                    INVOKE_WCB(*window, Mouse, (GLUT_MIDDLE_BUTTON, GLUT_UP, position[0], position[1]));
                }

                // Fire a move event if none of the buttons changed.
                if (left_move || move) {
                    handle_left_mouse(position[0], position[1], size[1], SCREEN_EVENT_MTOUCH_MOVE, window);
                }

                if (wheel) {
                    /* Very slightly modified from fg_main_mswin.
                     * Because we don't want MouseWheel to be called every. single. time.
                     * That the action occurs, we mimic the Windows version with "wheel deltas"
                     * XXX Do we even want this?
                     * XXX If we want this, it's possible to get horizontal scroll as well.
                     * XXX -Vertical scroll=wheel 0, horizontal=wheel 1? */
                    fgState.MouseWheelTicks -= wheel;
                    if (abs(fgState.MouseWheelTicks) >= WHEEL_DELTA)
                    {
                        int wheel_number = 0;
                        int direction = (fgState.MouseWheelTicks > 0) ? -1 : 1;

                        if (!FETCH_WCB(*window, MouseWheel) && !FETCH_WCB(*window, Mouse))
                            break;

                        //XXX fgSetWindow(window);

                        while(abs(fgState.MouseWheelTicks) >= WHEEL_DELTA)
                        {
                            if (FETCH_WCB(*window, MouseWheel))
                                INVOKE_WCB(*window, MouseWheel, (wheel_number, direction, window->State.MouseX, window->State.MouseY));
                            else /* No mouse wheel, call the mouse button callback twice */
                            {
                                /*
                                 * Map wheel zero to button 3 and 4; +1 to 3, -1 to 4
                                 *  "    "   one                     +1 to 5, -1 to 6, ...
                                 *
                                 * XXX The below assumes that you have no more than 3 mouse
                                 * XXX buttons.  Sorry.
                                 */
                                int button = wheel_number * 2 + 3;
                                if (direction < 0)
                                    ++button;
                                INVOKE_WCB(*window, Mouse, (button, GLUT_DOWN, window->State.MouseX, window->State.MouseY));
                                INVOKE_WCB(*window, Mouse, (button, GLUT_UP, window->State.MouseX, window->State.MouseY));
                            }

                            fgState.MouseWheelTicks -= WHEEL_DELTA * direction;
                        }
                    }
                }

                fgState.Modifiers = INVALID_MODIFIERS;
                break;
            }

            //Based off fg_main_android
            case SCREEN_EVENT_KEYBOARD:
            {
                int flags;
                int value;
                screen_get_event_property_iv(screenEvent, SCREEN_PROPERTY_KEY_FLAGS, &flags);
                screen_get_event_property_iv(screenEvent, SCREEN_PROPERTY_KEY_SYM, &value);
                screen_get_event_property_iv(screenEvent, SCREEN_PROPERTY_KEY_MODIFIERS, &mod);

                LOGI("fgPlatformProcessSingleEvent: SCREEN_EVENT_KEYBOARD. Flags: 0x%X, Sym: 0x%X, Mod: 0x%X", SLOG2_FA_SIGNED(flags), SLOG2_FA_SIGNED(value), SLOG2_FA_SIGNED(mod));

                /* Suppress key repeats if desired. Based off fg_main_mswin */
                if ((flags & KEY_REPEAT) == 0 || (fgState.KeyRepeat == GLUT_KEY_REPEAT_OFF && fgStructure.CurrentWindow->State.IgnoreKeyRepeat == GL_TRUE)) {
                    unsigned int keypress = 0;
                    unsigned char ascii = 0;

                    /* Remember the current modifiers state so user can query it from their callback */
                    fgState.Modifiers = fgPlatformGetModifiers(mod);

                    /* Process keys */
                    if ((keypress = key_special(value))) {
                        if(flags & KEY_DOWN) {
                            INVOKE_WCB(*window, Special, (keypress, window->State.MouseX, window->State.MouseY));
                        } else {
                            INVOKE_WCB(*window, SpecialUp, (keypress, window->State.MouseX, window->State.MouseY));
                        }
                    } else if((flags & KEY_SYM_VALID) && (ascii = key_ascii(value))) {
                        if(flags & KEY_DOWN) {
                            INVOKE_WCB(*window, Keyboard, (ascii, window->State.MouseX, window->State.MouseY));
                        } else {
                            INVOKE_WCB(*window, KeyboardUp, (ascii, window->State.MouseX, window->State.MouseY));
                        }
                    } else {
                        LOGW("fgPlatformProcessSingleEvent: SCREEN_EVENT_KEYBOARD. Unhandled key event");
                    }

                    fgState.Modifiers = INVALID_MODIFIERS;
                }
                break;
            }

            case SCREEN_EVENT_PROPERTY:
            case SCREEN_EVENT_IDLE:
                break;

            default:
                LOGW("fgPlatformProcessSingleEvent: unknown screen event: 0x%X", SLOG2_FA_SIGNED(eventType));
                break;
            }
        } else if (domain == navigator_get_domain()) {
            unsigned int eventType = bps_event_get_code(fgDisplay.pDisplay.event);
            switch (eventType) {

            case NAVIGATOR_WINDOW_STATE:
            {
                LOGI("fgPlatformProcessSingleEvent: NAVIGATOR_WINDOW_STATE");

                /* Covered only happens due to keyboard. When the app is minimized, the keyboard is closed.
                   When the keyboard is open, and the app is fullscreened, the keyboard is also closed.
                   If a window is covered and the app is minimized, the state will be set and the keyboard event
                   will adjust the screen size and change window status. */
                navigator_window_state_t state = navigator_event_get_window_state(fgDisplay.pDisplay.event);
                if(window->State.pWState.windowCovered == GL_FALSE)
                {
                    switch (state)
                    {
                    case NAVIGATOR_WINDOW_FULLSCREEN:
                        LOGI("fgPlatformProcessSingleEvent: NAVIGATOR_WINDOW_STATE-NAVIGATOR_WINDOW_FULLSCREEN");
                        window->State.Visible = GL_TRUE;
                        INVOKE_WCB(*window, WindowStatus, (GLUT_FULLY_RETAINED));
                        break;
                    case NAVIGATOR_WINDOW_THUMBNAIL:
                        LOGI("fgPlatformProcessSingleEvent: NAVIGATOR_WINDOW_STATE-NAVIGATOR_WINDOW_THUMBNAIL");
                        window->State.Visible = GL_TRUE;
                        INVOKE_WCB(*window, WindowStatus, (GLUT_PARTIALLY_RETAINED));
                        break;
                    case NAVIGATOR_WINDOW_INVISIBLE:
                        LOGI("fgPlatformProcessSingleEvent: NAVIGATOR_WINDOW_STATE-NAVIGATOR_WINDOW_INVISIBLE");
                        window->State.Visible = GL_FALSE;
                        INVOKE_WCB(*window, WindowStatus, (GLUT_HIDDEN));
                        break;
                    default:
                        LOGW("fgPlatformProcessSingleEvent: NAVIGATOR_WINDOW_STATE unknown: 0x%X", SLOG2_FA_SIGNED(state));
                        break;
                    }
                }
                window->State.pWState.windowState = state;
                break;
            }

            case NAVIGATOR_EXIT:
            {
                LOGI("fgPlatformProcessSingleEvent: NAVIGATOR_EXIT");

                fgPlatformMainLoopPostWork();

                /* User closed the application for good, let's kill the window */
                SFG_Window* window = fgStructure.CurrentWindow;
                if (window != NULL) {
                    fgDestroyWindow(window);
                } else {
                    LOGW("NAVIGATOR_EXIT: No current window");
                }

                //XXX Should this be a bit more "forceful" so that it doesn't continue to loop through events?
                break;
            }

            case NAVIGATOR_SWIPE_DOWN:
                /* XXX Open app menu */
                break;

            /* Orientation is a bunch of handshakes.
               - First the app get's asked if it wants to rotate (NAVIGATOR_ORIENTATION_CHECK)
               - If the app wants to rotate, then it will be told what size it will be after rotate (NAVIGATOR_ORIENTATION_SIZE).
               - Once the OS confirms that it's ready to rotate, it tells the app to handle rotation (NAVIGATOR_ORIENTATION).
               - Once rotation is complete, the OS tells the app it's done (NAVIGATOR_ORIENTATION_DONE) */
            case NAVIGATOR_ORIENTATION_CHECK:
                LOGI("fgPlatformProcessSingleEvent: NAVIGATOR_ORIENTATION_CHECK");

                /* Reset sizes */
                window->State.pWState.newWidth = 0;
                window->State.pWState.newHeight = 0;

#ifdef __PLAYBOOK__
                /* On rotation, the keyboard is closed. This prevents two resize calls */
                window->State.pWState.keyboardOpen = GL_FALSE;
#endif

                /* Notify that we want to rotate */
                navigator_orientation_check_response(fgDisplay.pDisplay.event, true);
                break;

            case NAVIGATOR_ORIENTATION:
                LOGI("fgPlatformProcessSingleEvent: NAVIGATOR_ORIENTATION");

                /* NAVIGATOR_ORIENTATION occurs before NAVIGATOR_KEYBOARD_POSITION */

                /* Rotate and resize the window */
                fgPlatformRotateWindow(window, navigator_event_get_orientation_angle(fgDisplay.pDisplay.event));
                fgPlatformFlushCommands();
#ifdef __PLAYBOOK__
                /* PlayBook doesn't indicate what the new size will be, so we need to retrieve it from the window itself */
                window->State.pWState.newWidth = glutGet(GLUT_WINDOW_WIDTH);
                window->State.pWState.newHeight = glutGet(GLUT_WINDOW_HEIGHT);
#endif
                fghOnReshapeNotify(window, window->State.pWState.newWidth, window->State.pWState.newHeight, GL_FALSE);

                /* Reset sizes */
                window->State.pWState.newWidth = 0;
                window->State.pWState.newHeight = 0;

                /* Done rotating */
                navigator_done_orientation(fgDisplay.pDisplay.event);
                break;

            case NAVIGATOR_BACK:
                LOGI("fgPlatformProcessSingleEvent: NAVIGATOR_BACK");
                INVOKE_WCB(*window, Keyboard, (ESCAPE_BUTTON_KEY, window->State.MouseX, window->State.MouseY));
                INVOKE_WCB(*window, KeyboardUp, (ESCAPE_BUTTON_KEY, window->State.MouseX, window->State.MouseY));
                break;

            case NAVIGATOR_WINDOW_ACTIVE:
                LOGI("fgPlatformProcessSingleEvent: NAVIGATOR_WINDOW_ACTIVE");
                INVOKE_WCB(*window, AppStatus, (GLUT_APPSTATUS_RESUME));
                break;

            case NAVIGATOR_WINDOW_INACTIVE:
                LOGI("fgPlatformProcessSingleEvent: NAVIGATOR_WINDOW_INACTIVE");
                INVOKE_WCB(*window, AppStatus, (GLUT_APPSTATUS_PAUSE));
                break;

            case NAVIGATOR_ORIENTATION_DONE:
            case NAVIGATOR_ORIENTATION_RESULT:
                LOGI("fgPlatformProcessSingleEvent: NAVIGATOR_ORIENTATION_DONE/NAVIGATOR_ORIENTATION_RESULT");
                break;

#ifndef __PLAYBOOK__
            case NAVIGATOR_KEYBOARD_STATE:
            {
                LOGI("fgPlatformProcessSingleEvent: NAVIGATOR_KEYBOARD_STATE");

                navigator_keyboard_state_t state = navigator_event_get_keyboard_state(fgDisplay.pDisplay.event);
                switch (state)
                {
                case NAVIGATOR_KEYBOARD_CLOSED:
                    LOGI("fgPlatformProcessSingleEvent: NAVIGATOR_KEYBOARD_STATE-NAVIGATOR_KEYBOARD_CLOSED");
                    /* NAVIGATOR_KEYBOARD_POSITION only occurs on open, so on keyboard close we need to reset the keyboard height */
                    fgPlatformHandleKeyboardHeight(window, 0);
                    break;
                case NAVIGATOR_KEYBOARD_OPENING:
                case NAVIGATOR_KEYBOARD_OPENED:
                case NAVIGATOR_KEYBOARD_CLOSING:
                    break;
                case NAVIGATOR_KEYBOARD_UNRECOGNIZED:
                    LOGW("fgPlatformProcessSingleEvent: NAVIGATOR_KEYBOARD_STATE-NAVIGATOR_KEYBOARD_UNRECOGNIZED");
                    break;
                default:
                    LOGW("fgPlatformProcessSingleEvent: NAVIGATOR_KEYBOARD_STATE unknown: 0x%X", SLOG2_FA_SIGNED(state));
                    break;
                }
                break;
            }

            case NAVIGATOR_KEYBOARD_POSITION:
            {
                /* Occurs only when keyboard has opened or resizes */
                LOGI("fgPlatformProcessSingleEvent: NAVIGATOR_KEYBOARD_POSITION");

                int keyboardOffset = navigator_event_get_keyboard_position(fgDisplay.pDisplay.event);
                if(keyboardOffset == BPS_FAILURE) {
                    LOGW("fgPlatformProcessSingleEvent: NAVIGATOR_KEYBOARD_POSITION: getting keyboard offset failed");
                } else {
                    /* keyboardOffset is the offset from the top of the screen to the top of the keyboard, AKA the size of the uncovered screen
                       We want the height of the keyboard. So instead of determining the orientation, getting the right display size, and subtracting;
                       we just get the keyboard height which may be slower but easier to understand and work with */
                    virtualkeyboard_get_height(&keyboardOffset);
                    fgPlatformHandleKeyboardHeight(window, keyboardOffset);
                }
                break;
            }

            case NAVIGATOR_DEVICE_LOCK_STATE:
                break;

            case NAVIGATOR_WINDOW_COVER:
            case NAVIGATOR_WINDOW_COVER_ENTER:
            case NAVIGATOR_WINDOW_COVER_EXIT:
                /* BlackBerry specific. Let app status and window status take care of everything */
                break;

            case NAVIGATOR_APP_STATE:
                /* Can do the same as NAVIGATOR_WINDOW_ACTIVE/NAVIGATOR_WINDOW_INACTIVE but
                   seems like it doesn't work when the app comes to the foreground. Might be a bug */
                break;

            case NAVIGATOR_ORIENTATION_SIZE:
                LOGI("fgPlatformProcessSingleEvent: NAVIGATOR_ORIENTATION_SIZE");

                /* Get new window size */
                window->State.pWState.newWidth = navigator_event_get_orientation_size_width(fgDisplay.pDisplay.event);
                window->State.pWState.newHeight = navigator_event_get_orientation_size_height(fgDisplay.pDisplay.event);
                break;
#endif

            case 0: //Doesn't exist in header, but shows up when keyboard shows and resizes
                break;

            default:
                LOGW("fgPlatformProcessSingleEvent: unknown navigator event: 0x%X", SLOG2_FA_SIGNED(eventType));
                break;
            }
        }
#ifdef __PLAYBOOK__
        /* While this could be used for non-PlayBook, BlackBerry 10 will still get navigator events, so use those. They are a bit more exact. */
        else if(domain == virtualkeyboard_get_domain()) {
            unsigned int eventType = bps_event_get_code(fgDisplay.pDisplay.event);
            switch (eventType) {
            case VIRTUALKEYBOARD_EVENT_VISIBLE:
                LOGI("fgPlatformProcessSingleEvent: VIRTUALKEYBOARD_EVENT_VISIBLE");
                if(window->State.pWState.keyboardOpen != GL_TRUE) {
                    window->State.pWState.keyboardOpen = GL_TRUE;
                    fgPlatformHandleKeyboardHeight(window, window->State.pWState.keyboardHeight);
                }
                break;

            case VIRTUALKEYBOARD_EVENT_HIDDEN:
                LOGI("fgPlatformProcessSingleEvent: VIRTUALKEYBOARD_EVENT_HIDDEN");
                if(window->State.pWState.keyboardOpen != GL_FALSE) {
                    window->State.pWState.keyboardOpen = GL_FALSE;
                    fgPlatformHandleKeyboardHeight(window, 0);
                }
                break;

            case VIRTUALKEYBOARD_EVENT_INFO:
                LOGI("fgPlatformProcessSingleEvent: VIRTUALKEYBOARD_EVENT_INFO");
                window->State.pWState.keyboardHeight = virtualkeyboard_event_get_height(fgDisplay.pDisplay.event);
                if(window->State.pWState.keyboardOpen == GL_TRUE) {
                    fgPlatformHandleKeyboardHeight(window, window->State.pWState.keyboardHeight);
                }
                break;

            default:
                LOGW("fgPlatformProcessSingleEvent: unknown virtualkeyboard event: 0x%X", eventType);
                break;
            }
        }
#endif
    } while(bps_get_event(&fgDisplay.pDisplay.event, 1) == BPS_SUCCESS && fgDisplay.pDisplay.event != NULL);

    /* Reset event to reduce chances of triggering something */
    fgDisplay.pDisplay.event = NULL;
}