void CCEGLView::onTouchesMove(int id[], float x[], float y[], int pointerNumber) { result r = E_SUCCESS; CCSet set; for(int i = 0 ; i < pointerNumber ; i++ ) { CCLOG("Moving touches with id: %d, x=%f, y=%f", id[i], x[i], y[i]); CCTouch *pTouch = NULL; r = s_mapTouches.GetValue(id[i], pTouch); if (E_SUCCESS == r && pTouch != NULL) { pTouch->SetTouchInfo(0, (x[i] - m_rcViewPort.origin.x) / m_fScreenScaleFactor , (y[i] - m_rcViewPort.origin.y) / m_fScreenScaleFactor); set.addObject(pTouch); } else { // It is error, should return. CCLOG("Moving touches with id: %d error", id[i]); return; } } m_pDelegate->touchesMoved(&set, NULL); }
void CCEGLView::OnPointerPressed(int id, const CCPoint& point) { // prepare CCTouch CCTouch* pTouch = m_pTouches[id]; if (! pTouch) { pTouch = new CCTouch(); m_pTouches[id] = pTouch; } // prepare CCSet CCSet* pSet = m_pSets[id]; if (! pSet) { pSet = new CCSet(); m_pSets[id] = pSet; } if (! pTouch || ! pSet) return; float x = point.x; float y = point.y; ConvertPointerCoords(x, y); pTouch->SetTouchInfo(x, y); pSet->addObject(pTouch); m_pDelegate->touchesBegan(pSet, NULL); }
Boolean CCXEGLView::OnPenUp(EventType* pEvent, Int32 nIndex) { if (m_pDelegate && nIndex < MAX_TOUCHES) { CCTouch* pTouch = s_pTouches[nIndex]; if (pTouch) { NSSet set; pTouch->SetTouchInfo(0, (float)pEvent->sParam1, (float)pEvent->sParam2); set.addObject(pTouch); m_pDelegate->touchesEnded(&set, NULL); pTouch->release(); for (Int32 i = nIndex; i < MAX_TOUCHES; ++i) { if (i != (MAX_TOUCHES - 1)) { s_pTouches[i] = s_pTouches[i + 1]; } else { s_pTouches[i] = NULL; } } } } return FALSE; }
Boolean CCEGLView::OnPenMove(EventType* pEvent) { do { CC_BREAK_IF(!m_pDelegate); Int32 nCount = EvtGetPenMultiPointCount(pEvent); CC_BREAK_IF(nCount <= 0 || nCount > MAX_TOUCHES); CCSet set; Int32 nPosX, nPosY; for (Int32 i = 0; i < nCount; ++i) { CCTouch* pTouch = s_pTouches[i]; CC_BREAK_IF(!pTouch); EvtGetPenMultiPointXY(pEvent, i, &nPosX, &nPosY); pTouch->SetTouchInfo(0, (float) nPosX, (float) nPosY); set.addObject(pTouch); } m_pDelegate->touchesMoved(&set, NULL); } while (0); return FALSE; }
Boolean CCEGLView::OnPenUp(EventType* pEvent, Int32 nIndex) { if (m_pDelegate && nIndex < MAX_TOUCHES) { CCTouch* pTouch = s_pTouches[nIndex]; if (pTouch) { CCSet set; pTouch->SetTouchInfo(0, (float)(pEvent->sParam1 - m_rcViewPort.X()) / m_fScreenScaleFactor, (float)(pEvent->sParam2 - m_rcViewPort.Y()) / m_fScreenScaleFactor); set.addObject(pTouch); m_pDelegate->touchesEnded(&set, NULL); pTouch->release(); for (Int32 i = nIndex; i < MAX_TOUCHES; ++i) { if (i != (MAX_TOUCHES - 1)) { s_pTouches[i] = s_pTouches[i + 1]; } else { s_pTouches[i] = NULL; } } } } return FALSE; }
void CCEGLView::OnPointerMoved(int id, const CCPoint& point) { CCTouch* pTouch = m_pTouches[id]; CCSet* pSet = m_pSets[id]; if (! pTouch || ! pSet) return; float x = point.x; float y = point.y; ConvertPointerCoords(x, y); pTouch->SetTouchInfo(x, y); m_pDelegate->touchesMoved(pSet, NULL); }
void CCTouchDispatcher::OnPointerOn(const InputPointerEvent* evt) { CCSet set; CCTouch* pTouch = new CCTouch(); pTouch->SetTouchInfo(0, evt->getPos().x, evt->getPos().y); set.addObject(pTouch); m_Touches.insert(std::make_pair(evt->getSource(), pTouch)); pTouch->retain(); // LOG(0, ".. on %.3f %.3f\n", evt->GetPos().x, evt->GetPos().y); touchesBegan(&set); }
void CCTouchDispatcher::OnPointerDrag(const InputPointerEvent* evt) { map<Ref<InputPointer>, CCTouch*>::type::iterator itr = m_Touches.find(evt->getSource()); if (itr == m_Touches.end()) return; CCSet set; CCTouch* pTouch = itr->second; pTouch->SetTouchInfo(0, evt->getPos().x, evt->getPos().y); set.addObject(pTouch); // LOG(0, ".. drag %.3f %.3f\n", evt->GetPos().x, evt->GetPos().y); touchesMoved(&set); }
Boolean CCXEGLView::OnPenDown(EventType* pEvent, Int32 nIndex) { if (m_pDelegate && nIndex < MAX_TOUCHES) { CCTouch* pTouch = s_pTouches[nIndex]; if (!pTouch) { pTouch = new CCTouch; } pTouch->SetTouchInfo(0, (float)pEvent->sParam1, (float)pEvent->sParam2); s_pTouches[nIndex] = pTouch; NSSet set; set.addObject(pTouch); m_pDelegate->touchesBegan(&set, NULL); } return FALSE; }
void CCEGLView::OnPointerReleased(int id, const CCPoint& point) { CCTouch* pTouch = m_pTouches[id]; CCSet* pSet = m_pSets[id]; if (! pTouch || ! pSet) return; float x = point.x; float y = point.y; ConvertPointerCoords(x, y); pTouch->SetTouchInfo(x, y); m_pDelegate->touchesEnded(pSet, NULL); pSet->removeObject(pTouch); CC_SAFE_DELETE(m_pTouches[id]); CC_SAFE_DELETE(m_pSets[id]); }
void CCEGLView::onTouchesEnd(int id[], float x[], float y[], int pointerNumber) { result r = E_SUCCESS; CCSet set; for(int i = 0 ; i < pointerNumber ; i++ ) { CCTouch *pTouch = NULL; r = s_mapTouches.GetValue(id[i], pTouch); if (E_SUCCESS == r && pTouch != NULL) { pTouch->SetTouchInfo(0, (x[i] - m_rcViewPort.origin.x) / m_fScreenScaleFactor , (y[i] - m_rcViewPort.origin.y) / m_fScreenScaleFactor); set.addObject(pTouch); s_mapTouches.Remove(id[i]); pTouch->release(); CCLOG("Ending touches with id: %d, x=%f, y=%f, retain count = %d", id[i], x[i], y[i], pTouch->retainCount()); } } m_pDelegate->touchesEnded(&set, NULL); }
Boolean CCEGLView::OnPenDown(EventType* pEvent, Int32 nIndex) { if (m_pDelegate && nIndex < MAX_TOUCHES) { CCTouch* pTouch = s_pTouches[nIndex]; if (!pTouch) { pTouch = new CCTouch; } pTouch->SetTouchInfo(0, (float)(pEvent->sParam1 - m_rcViewPort.X()) / m_fScreenScaleFactor, (float)(pEvent->sParam2 - m_rcViewPort.Y()) / m_fScreenScaleFactor); s_pTouches[nIndex] = pTouch; CCSet set; set.addObject(pTouch); m_pDelegate->touchesBegan(&set, NULL); } return FALSE; }
void CCEGLView::onTouchesBegin(int id[], float x[], float y[], int pointerNumber) { result r = E_SUCCESS; CCSet set; for(int i = 0 ; i < pointerNumber ; i++ ) { CCTouch *pTouch = NULL; r = s_mapTouches.GetValue(id[i], pTouch); if (E_OBJ_NOT_FOUND == r && NULL == pTouch) { pTouch = new CCTouch(); pTouch->SetTouchInfo(0, (x[i] - m_rcViewPort.origin.x) / m_fScreenScaleFactor, (y[i] - m_rcViewPort.origin.y) / m_fScreenScaleFactor); s_mapTouches.Add(id[i], pTouch); set.addObject(pTouch); m_pDelegate->touchesBegan(&set, NULL); } else { CCLOG("Beginnig touches with id: %d error", id[i]); } } }
// handle touch event void Java_org_cocos2dx_lib_Cocos2dxRenderer_nativeTouchesBegin(JNIEnv* env, jobject thiz, jint id, jfloat x, jfloat y) { CCRect rcRect = CCEGLView::sharedOpenGLView().getViewPort(); CCSet set; CCTouch *pTouch = s_pTouches[id]; if (! pTouch) { LOGD("Beginning touches with id: %d, x=%f, y=%f", id, x, y); pTouch = new CCTouch(); pTouch->SetTouchInfo(0, x - rcRect.origin.x, y - rcRect.origin.y, id); s_pTouches[id] = pTouch; set.addObject(pTouch); cocos2d::CCDirector::sharedDirector()->getOpenGLView()->getDelegate()->touchesBegan(&set, NULL); } else { LOGD("Beginnig touches with id: %d error", id); } }
void Java_org_cocos2dx_lib_Cocos2dxRenderer_nativeTouchesEnd(JNIEnv* env, jobject thiz, jint id, jfloat x, jfloat y) { CCRect rcRect = CCEGLView::sharedOpenGLView().getViewPort(); CCSet set; /* Add to the set to send to the director */ CCTouch* pTouch = s_pTouches[id]; if (pTouch) { LOGD("Ending touches with id: %d, x=%f, y=%f", id, x, y); pTouch->SetTouchInfo(0, x - rcRect.origin.x , y - rcRect.origin.y, id); set.addObject(pTouch); // release the object pTouch->release(); s_pTouches[id] = NULL; cocos2d::CCDirector::sharedDirector()->getOpenGLView()->getDelegate()->touchesEnded(&set, NULL); } else { LOGD("Ending touches with id: %d error", id); } }
bool CCEGLView::HandleEvents() { bps_event_t* event = NULL; mtouch_event_t mtouch_event; int touch_id = 0; int val = 0; int rc = 0; int domain = 0; char buf[4] = {0}; for (;;) { rc = bps_get_event(&event, 1); assert(rc == BPS_SUCCESS); #ifdef BPS_EVENTS // break if no more events if (event == NULL) break; #else if (event != NULL) { #endif if (m_pEventHandler && m_pEventHandler->HandleBPSEvent(event)) continue; domain = bps_event_get_domain(event); if (domain == navigator_get_domain()) { switch (bps_event_get_code(event)) { case NAVIGATOR_SWIPE_DOWN: CCKeypadDispatcher::sharedDispatcher()->dispatchKeypadMSG(kTypeMenuClicked); break; case NAVIGATOR_EXIT: // exit the application // release(); break; case NAVIGATOR_WINDOW_INACTIVE: if(m_isWindowActive) { CCApplication::sharedApplication().applicationDidEnterBackground(); m_isWindowActive = false; } break; case NAVIGATOR_WINDOW_ACTIVE: if(!m_isWindowActive) { CCApplication::sharedApplication().applicationWillEnterForeground(); m_isWindowActive = true; } break; case NAVIGATOR_WINDOW_STATE: { switch(navigator_event_get_window_state(event)) { case NAVIGATOR_WINDOW_FULLSCREEN: if(!m_isWindowActive) { CCApplication::sharedApplication().applicationWillEnterForeground(); m_isWindowActive = true; } break; case NAVIGATOR_WINDOW_THUMBNAIL: if(m_isWindowActive) { CCApplication::sharedApplication().applicationDidEnterBackground(); m_isWindowActive = false; } break; } break; } default: break; } } } #ifndef BPS_EVENTS // for now handle screen events separately from BPS events if (screen_get_event(m_screenContext, m_screenEvent, 0) < 0) { // we have an error condition in the screen event break; } else { #else else if (domain == screen_get_domain()) { m_screenEvent = screen_event_get_event(event); #endif rc = screen_get_event_property_iv(m_screenEvent, SCREEN_PROPERTY_TYPE, &val); if (rc || val == SCREEN_EVENT_NONE) break; switch (val) { case SCREEN_EVENT_CLOSE: fprintf(stderr, "SCREEN CLOSE EVENT!\n"); break; case SCREEN_EVENT_MTOUCH_RELEASE: screen_get_mtouch_event(m_screenEvent, &mtouch_event, 0); touch_id = mtouch_event.contact_id; if (m_pDelegate && touch_id < MAX_TOUCHES) { CCTouch* touch = s_pTouches[touch_id]; if (touch) { CCSet set; touch->SetTouchInfo(((float)(mtouch_event.x) - m_rcViewPort.origin.x) / m_fScreenScaleFactor, ((float)(mtouch_event.y) - m_rcViewPort.origin.y) / m_fScreenScaleFactor); set.addObject(touch); m_pDelegate->touchesEnded(&set, NULL); touch->release(); for (int i = touch_id; i < MAX_TOUCHES; i++) { if (i != (MAX_TOUCHES - 1)) { s_pTouches[i] = s_pTouches[i + 1]; } else { s_pTouches[i] = NULL; } } } } break; case SCREEN_EVENT_MTOUCH_TOUCH: screen_get_mtouch_event(m_screenEvent, &mtouch_event, 0); touch_id = mtouch_event.contact_id; if (m_pDelegate && touch_id < MAX_TOUCHES) { CCTouch* touch = s_pTouches[touch_id]; if (!touch) touch = new CCTouch; touch->SetTouchInfo(((float)(mtouch_event.x) - m_rcViewPort.origin.x) / m_fScreenScaleFactor, ((float)(mtouch_event.y) - m_rcViewPort.origin.y) / m_fScreenScaleFactor); s_pTouches[touch_id] = touch; CCSet set; set.addObject(touch); m_pDelegate->touchesBegan(&set, NULL); } break; case SCREEN_EVENT_MTOUCH_MOVE: screen_get_mtouch_event(m_screenEvent, &mtouch_event, 0); touch_id = mtouch_event.contact_id; if (m_pDelegate && touch_id < MAX_TOUCHES) { CCTouch* touch = s_pTouches[touch_id]; if (touch) { CCSet set; touch->SetTouchInfo(((float)(mtouch_event.x) - m_rcViewPort.origin.x) / m_fScreenScaleFactor, ((float)(mtouch_event.y) - m_rcViewPort.origin.y) / m_fScreenScaleFactor); set.addObject(touch); m_pDelegate->touchesMoved(&set, NULL); } } break; case SCREEN_EVENT_POINTER: { int buttons; int pair[2]; static bool mouse_pressed = false; // this is a mouse move event, it is applicable to a device with a usb mouse or simulator screen_get_event_property_iv(m_screenEvent, SCREEN_PROPERTY_BUTTONS, &buttons); screen_get_event_property_iv(m_screenEvent, SCREEN_PROPERTY_SOURCE_POSITION, pair); if (buttons & SCREEN_LEFT_MOUSE_BUTTON) { if (mouse_pressed) { // Left mouse button was released if (m_pDelegate && touch_id < MAX_TOUCHES) { CCTouch* touch = s_pTouches[touch_id]; if (touch) { CCSet set; touch->SetTouchInfo(((float)(pair[0]) - m_rcViewPort.origin.x) / m_fScreenScaleFactor, ((float)(pair[1]) - m_rcViewPort.origin.y) / m_fScreenScaleFactor); set.addObject(touch); m_pDelegate->touchesMoved(&set, NULL); } } } else { // Left mouse button is pressed mouse_pressed = true; if (m_pDelegate && touch_id < MAX_TOUCHES) { CCTouch* touch = s_pTouches[touch_id]; if (!touch) touch = new CCTouch; touch->SetTouchInfo(((float)(pair[0]) - m_rcViewPort.origin.x) / m_fScreenScaleFactor, ((float)(pair[1]) - m_rcViewPort.origin.y) / m_fScreenScaleFactor); s_pTouches[touch_id] = touch; CCSet set; set.addObject(touch); m_pDelegate->touchesBegan(&set, NULL); } } } else { if (mouse_pressed) { if (m_pDelegate && touch_id < MAX_TOUCHES) { mouse_pressed = false; CCTouch* touch = s_pTouches[touch_id]; if (touch) { CCSet set; touch->SetTouchInfo(((float)(pair[0]) - m_rcViewPort.origin.x) / m_fScreenScaleFactor, ((float)(pair[1]) - m_rcViewPort.origin.y) / m_fScreenScaleFactor); set.addObject(touch); m_pDelegate->touchesEnded(&set, NULL); touch->release(); for (int i = touch_id; i < MAX_TOUCHES; i++) { if (i != (MAX_TOUCHES - 1)) { s_pTouches[i] = s_pTouches[i + 1]; } else { s_pTouches[i] = NULL; } } } } } } } break; case SCREEN_EVENT_KEYBOARD: screen_get_event_property_iv(m_screenEvent, SCREEN_PROPERTY_KEY_FLAGS, &val); if (val & KEY_DOWN) { screen_get_event_property_iv(m_screenEvent, SCREEN_PROPERTY_KEY_SYM, &val); if (val >= ' ' && val < '~') { buf[0] = val; buf[1]= '\0'; CCIMEDispatcher::sharedDispatcher()->dispatchInsertText(buf, 1); } else { val = val - 0xf000; buf[0] = val; buf[1]= '\0'; switch (val) { case 8: // backspace // CCKeypadDispatcher::sharedDispatcher()->dispatchKeypadMSG(kTypeBackClicked); CCIMEDispatcher::sharedDispatcher()->dispatchDeleteBackward(); break; default: CCIMEDispatcher::sharedDispatcher()->dispatchInsertText(buf, 1); break; } } } break; default: break; } } } return true; } void CCEGLView::swapBuffers() { eglSwapBuffers(m_eglDisplay, m_eglSurface); }
bool CCEGLView::HandleEvents() { bps_event_t* event = NULL; mtouch_event_t mtouch_event; int touch_id = 0; int val = 0; int rc = 0; int domain = 0; char buf[4] = {0}; #ifdef BPS_EVENTS for (;;) { rc = bps_get_event(&event, 1); assert(rc == BPS_SUCCESS); // break if no more events if (event == NULL) break; domain = bps_event_get_domain(event); if (domain == screen_get_domain()) { m_screenEvent = screen_event_get_event(event); #else while (!screen_get_event(m_screenContext, m_screenEvent, 0)) { #endif rc = screen_get_event_property_iv(m_screenEvent, SCREEN_PROPERTY_TYPE, &val); if (rc || val == SCREEN_EVENT_NONE) break; switch (val) { case SCREEN_EVENT_CLOSE: fprintf(stderr, "SCREEN CLOSE EVENT!\n"); break; case SCREEN_EVENT_MTOUCH_RELEASE: screen_get_mtouch_event(m_screenEvent, &mtouch_event, 0); touch_id = mtouch_event.contact_id; if (m_pDelegate && touch_id < MAX_TOUCHES) { CCTouch* touch = s_pTouches[touch_id]; if (touch) { CCSet set; touch->SetTouchInfo(0, ((float)(mtouch_event.x) - m_rcViewPort.origin.x) / m_fScreenScaleFactor, ((float)(mtouch_event.y) - m_rcViewPort.origin.y) / m_fScreenScaleFactor); set.addObject(touch); m_pDelegate->touchesEnded(&set, NULL); touch->release(); for (int i = touch_id; i < MAX_TOUCHES; i++) { if (i != (MAX_TOUCHES - 1)) { s_pTouches[i] = s_pTouches[i + 1]; } else { s_pTouches[i] = NULL; } } } } break; case SCREEN_EVENT_MTOUCH_TOUCH: screen_get_mtouch_event(m_screenEvent, &mtouch_event, 0); touch_id = mtouch_event.contact_id; if (m_pDelegate && touch_id < MAX_TOUCHES) { CCTouch* touch = s_pTouches[touch_id]; if (!touch) touch = new CCTouch; touch->SetTouchInfo(0, ((float)(mtouch_event.x) - m_rcViewPort.origin.x) / m_fScreenScaleFactor, ((float)(mtouch_event.y) - m_rcViewPort.origin.y) / m_fScreenScaleFactor); s_pTouches[touch_id] = touch; CCSet set; set.addObject(touch); m_pDelegate->touchesBegan(&set, NULL); } break; case SCREEN_EVENT_MTOUCH_MOVE: screen_get_mtouch_event(m_screenEvent, &mtouch_event, 0); touch_id = mtouch_event.contact_id; if (m_pDelegate && touch_id < MAX_TOUCHES) { CCTouch* touch = s_pTouches[touch_id]; if (touch) { CCSet set; touch->SetTouchInfo(0, ((float)(mtouch_event.x) - m_rcViewPort.origin.x) / m_fScreenScaleFactor, ((float)(mtouch_event.y) - m_rcViewPort.origin.y) / m_fScreenScaleFactor); set.addObject(touch); // we can likely optimize this call and move it outside of the while loop and just call at the end if we // have a bunch of move touches all in a row m_pDelegate->touchesMoved(&set, NULL); } } break; case SCREEN_EVENT_POINTER: { int buttons; int pair[2]; static bool mouse_pressed = false; //This is a mouse move event, it is applicable to a device with a usb mouse or simulator screen_get_event_property_iv(m_screenEvent, SCREEN_PROPERTY_BUTTONS, &buttons); screen_get_event_property_iv(m_screenEvent, SCREEN_PROPERTY_SOURCE_POSITION, pair); if (buttons == SCREEN_LEFT_MOUSE_BUTTON) { if (mouse_pressed) { //Left mouse button was released, add a cube if (m_pDelegate && touch_id < MAX_TOUCHES) { CCTouch* touch = s_pTouches[touch_id]; if (touch) { CCSet set; touch->SetTouchInfo(0, ((float)(pair[0]) - m_rcViewPort.origin.x) / m_fScreenScaleFactor, ((float)(pair[1]) - m_rcViewPort.origin.y) / m_fScreenScaleFactor); set.addObject(touch); // we can likely optimize this call and move it outside of the while loop and just call at the end if we // have a bunch of move touches all in a row m_pDelegate->touchesMoved(&set, NULL); } } } else { //Left mouse button is pressed mouse_pressed = true; if (m_pDelegate && touch_id < MAX_TOUCHES) { CCTouch* touch = s_pTouches[touch_id]; if (!touch) touch = new CCTouch; touch->SetTouchInfo(0, ((float)(pair[0]) - m_rcViewPort.origin.x) / m_fScreenScaleFactor, ((float)(pair[1]) - m_rcViewPort.origin.y) / m_fScreenScaleFactor); s_pTouches[touch_id] = touch; CCSet set; set.addObject(touch); m_pDelegate->touchesBegan(&set, NULL); } } } else { if (mouse_pressed) { if (m_pDelegate && touch_id < MAX_TOUCHES) { mouse_pressed = false; CCTouch* touch = s_pTouches[touch_id]; if (touch) { CCSet set; touch->SetTouchInfo(0, ((float)(pair[0]) - m_rcViewPort.origin.x) / m_fScreenScaleFactor, ((float)(pair[1]) - m_rcViewPort.origin.y) / m_fScreenScaleFactor); set.addObject(touch); m_pDelegate->touchesEnded(&set, NULL); touch->release(); for (int i = touch_id; i < MAX_TOUCHES; i++) { if (i != (MAX_TOUCHES - 1)) { s_pTouches[i] = s_pTouches[i + 1]; } else { s_pTouches[i] = NULL; } } } } } } } break; case SCREEN_EVENT_KEYBOARD: screen_get_event_property_iv(m_screenEvent, SCREEN_PROPERTY_KEY_FLAGS, &val); if (val & KEY_DOWN) { screen_get_event_property_iv(m_screenEvent, SCREEN_PROPERTY_KEY_SYM, &val); if (val >= ' ' && val < '~') { buf[0] = val; buf[1]= '\0'; CCIMEDispatcher::sharedDispatcher()->dispatchInsertText(buf, 1); } else { val = val - 0xf000; buf[0] = val; buf[1]= '\0'; switch (val) { case 8: // backspace // CCKeypadDispatcher::sharedDispatcher()->dispatchKeypadMSG(kTypeBackClicked); CCIMEDispatcher::sharedDispatcher()->dispatchDeleteBackward(); break; default: CCIMEDispatcher::sharedDispatcher()->dispatchInsertText(buf, 1); break; } } } break; default: break; } } #ifdef BPS_EVENTS else if (domain == navigator_get_domain()) { switch (bps_event_get_code(event)) { case NAVIGATOR_SWIPE_DOWN: CCKeypadDispatcher::sharedDispatcher()->dispatchKeypadMSG(kTypeMenuClicked); break; case NAVIGATOR_EXIT: fprintf(stderr, "navigator exit\n"); // exit the application release(); break; } } }