int Loop::getIndexOfNote(int noteNumber, double time, bool exact) { if (!exact) { for (int i=0;i<getNumEvents();i++) { if (getEventPointer(i)->message.isNoteOn() && getEventPointer(i)->message.getNoteNumber()==noteNumber && (getEventTime(i)<=time && getTimeOfMatchingKeyUp(i)>time)) { return i; } } } else { for (int i=0;i<getNumEvents();i++) { if (getEventPointer(i)->message.isNoteOn() && getEventPointer(i)->message.getNoteNumber()==noteNumber && fabs(getEventTime(i)-time)<1.0) { return i; } } } return No_Note; }
mir::EventUPtr mia::Lexicon::translate(droidinput::InputEvent const* android_event) { switch(android_event->getType()) { case AINPUT_EVENT_TYPE_KEY: { auto kev = static_cast<const droidinput::KeyEvent*>(android_event); return mev::make_event(MirInputDeviceId(android_event->getDeviceId()), kev->getEventTime(), kev->getMac(), mia::mir_keyboard_action_from_android(kev->getAction(), kev->getRepeatCount()), kev->getKeyCode(), kev->getScanCode(), mia::mir_modifiers_from_android(kev->getMetaState())); } case AINPUT_EVENT_TYPE_MOTION: { if (mia::android_source_id_is_pointer_device(android_event->getSource())) { auto mev = static_cast<const droidinput::MotionEvent*>(android_event); return mev::make_event(MirInputDeviceId(android_event->getDeviceId()), mev->getEventTime(), mev->getMac(), mia::mir_modifiers_from_android(mev->getMetaState()), mia::mir_pointer_action_from_masked_android(mev->getAction() & AMOTION_EVENT_ACTION_MASK), mia::mir_pointer_buttons_from_android(mev->getButtonState()), mev->getX(0), mev->getY(0), mev->getRawAxisValue(AMOTION_EVENT_AXIS_HSCROLL, 0), mev->getRawAxisValue(AMOTION_EVENT_AXIS_VSCROLL, 0), mev->getRawAxisValue(AMOTION_EVENT_AXIS_RX, 0), mev->getRawAxisValue(AMOTION_EVENT_AXIS_RY, 0)); } else { auto mev = static_cast<const droidinput::MotionEvent*>(android_event); auto ev = mev::make_event(MirInputDeviceId(android_event->getDeviceId()), mev->getEventTime(), mev->getMac(), mia::mir_modifiers_from_android(mev->getMetaState())); auto action = mev->getAction(); size_t index_with_action = (action & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK) >> AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT; auto masked_action = action & AMOTION_EVENT_ACTION_MASK; for (unsigned i = 0; i < mev->getPointerCount(); i++) { auto action = (i == index_with_action) ? mia::mir_touch_action_from_masked_android(masked_action) : mir_touch_action_change; mev::add_touch(*ev, mev->getPointerId(i), action, mia::mir_tool_type_from_android(mev->getToolType(i)), mev->getX(i), mev->getY(i), mev->getPressure(i), mev->getTouchMajor(i), mev->getTouchMinor(i), mev->getSize(i)); } return ev; } } default: BOOST_THROW_EXCEPTION(std::logic_error("Invalid android event")); } }
static uint8* findEventAfter (uint8* d, uint8* endData, const int samplePosition) noexcept { while (d < endData && getEventTime (d) <= samplePosition) d += getEventTotalSize (d); return d; }
/** * Update StWindow position according to native parent position. */ void StWindowImpl::updateChildRect() { if(!attribs.IsFullScreen && (Window )myParentWin != 0 && !myMaster.stXDisplay.isNull()) { Display* hDisplay = myMaster.stXDisplay->hDisplay; Window dummyWin; int xReturn, yReturn; unsigned int widthReturn, heightReturn, uDummy; XGetGeometry(hDisplay, (Window )myParentWin, &dummyWin, &xReturn, &yReturn, &widthReturn, &heightReturn, &uDummy, &uDummy); XTranslateCoordinates(hDisplay, (Window )myParentWin, myMaster.stXDisplay->getRootWindow(), 0, 0, &myRectNorm.left(), &myRectNorm.top(), &dummyWin); myRectNorm.right() = myRectNorm.left() + widthReturn; myRectNorm.bottom() = myRectNorm.top() + heightReturn; // update only when changes if(myRectNorm != myRectNormPrev) { myRectNormPrev = myRectNorm; myIsUpdated = true; const StRectI_t& aRect = attribs.IsFullScreen ? myRectFull : myRectNorm; myStEvent.Type = stEvent_Size; myStEvent.Size.Time = getEventTime(); myStEvent.Size.SizeX = aRect.width(); myStEvent.Size.SizeY = aRect.height(); signals.onResize->emit(myStEvent.Size); } } }
void Loop::cleanZeroLengthNotes() { Array<int> matchedNoteOffs; for (int i=0;i<getNumEvents();i++) { if (getEventPointer(i)->message.isNoteOn()) { if (getEventTime(i) == getTimeOfMatchingKeyUp(i) || getTimeOfMatchingKeyUp(i)==0.0) { //zero length note deleteEvent(i,(getTimeOfMatchingKeyUp(i)!=0.0)); updateMatchedPairs(); } } } for (int i=0;i<getNumEvents();i++) { if (getEventPointer(i)->message.isNoteOn() && getIndexOfMatchingKeyUp(i)!=-1) matchedNoteOffs.add(getIndexOfMatchingKeyUp(i)); } for (int i=0;i<getNumEvents();i++) { if (getEventPointer(i)->message.isNoteOff() && !matchedNoteOffs.contains(i)) { //unmatched note-off deleteEvent(i,false); updateMatchedPairs(); break; } } //updateMatchedPairs(); }
void StWindowImpl::updateWindowPos() { if(myMaster.hRC.isNull()) { return; } EGLint aWidth = 0, aHeight = 0; if(myMaster.hWindowGl != NULL) { aWidth = ANativeWindow_getWidth (myMaster.hWindowGl); aHeight = ANativeWindow_getHeight(myMaster.hWindowGl); } else if(myMaster.eglSurface != EGL_NO_SURFACE) { eglQuerySurface(myMaster.hRC->getDisplay(), myMaster.eglSurface, EGL_WIDTH, &aWidth); eglQuerySurface(myMaster.hRC->getDisplay(), myMaster.eglSurface, EGL_HEIGHT, &aHeight); } else { return; } if(myRectNorm.width() == aWidth && myRectNorm.height() == aHeight) { return; } myRectNorm.left() = 0; myRectNorm.top() = 0; myRectNorm.right() = myRectNorm.left() + aWidth; myRectNorm.bottom() = myRectNorm.top() + aHeight; myRectFull = myRectNorm; myStEvent.Size.init(getEventTime(), myRectNorm.width(), myRectNorm.height(), myForcedAspect); signals.onResize->emit(myStEvent.Size); }
int GtkClickCounter::clickCountForGdkButtonEvent(GtkWidget* widget, GdkEventButton* buttonEvent) { gint doubleClickDistance = 250; gint doubleClickTime = 5; GtkSettings* settings = gtk_settings_get_for_screen(gtk_widget_get_screen(widget)); g_object_get(settings, "gtk-double-click-distance", &doubleClickDistance, "gtk-double-click-time", &doubleClickTime, NULL); // GTK+ only counts up to triple clicks, but WebCore wants to know about // quadruple clicks, quintuple clicks, ad infinitum. Here, we replicate the // GDK logic for counting clicks. GdkEvent* event(reinterpret_cast<GdkEvent*>(buttonEvent)); guint32 eventTime = getEventTime(event); if ((event->type == GDK_2BUTTON_PRESS || event->type == GDK_3BUTTON_PRESS) || ((abs(buttonEvent->x - m_previousClickPoint.x()) < doubleClickDistance) && (abs(buttonEvent->y - m_previousClickPoint.y()) < doubleClickDistance) && (eventTime - m_previousClickTime < static_cast<guint>(doubleClickTime)) && (buttonEvent->button == m_previousClickButton))) m_currentClickCount++; else m_currentClickCount = 1; gdouble x, y; gdk_event_get_coords(event, &x, &y); m_previousClickPoint = IntPoint(x, y); m_previousClickButton = buttonEvent->button; m_previousClickTime = eventTime; return m_currentClickCount; }
// function create GUI window bool StWindowImpl::create() { myKeysState.reset(); myInitState = STWIN_INITNOTSTART; myToResetDevice = false; if(myParentWin == NULL) { return false; } // retrieve fixed information myHasOrientSensor = myParentWin->hasOrientationSensor(); myIsPoorOrient = myParentWin->isPoorOrientationSensor(); myParentWin->signals.onInputEvent += stSlot(this, &StWindowImpl::onAndroidInput); myParentWin->signals.onAppCmd += stSlot(this, &StWindowImpl::onAndroidCommand); /*if(myParentWin->getSavedState() != NULL) { // we are starting with a previous saved state; restore from it myState = *(StSavedState* )myParentWin->getSavedState(); }*/ myIsUpdated = true; if(myParentWin->getWindow() != NULL) { // re-starting output for existing window return onAndroidInitWindow(); } // first start - wait for CommandId_WindowInit... int aPollRes = 0; int aNbEvents = 0; StAndroidPollSource* aSource = NULL; while((aPollRes = ALooper_pollAll(-1, NULL, &aNbEvents, (void** )&aSource)) >= 0) { if(aSource != NULL) { aSource->process(myParentWin, aSource); } if(myToResetDevice || myParentWin->ToDestroy()) { //myToResetDevice = true; myStEvent.Type = stEvent_Close; myStEvent.Close.Time = getEventTime(); signals.onClose->emit(myStEvent.Close); return false; } else if(myInitState != STWIN_INITNOTSTART) { break; } } return myInitState == STWIN_INIT_SUCCESS; }
/** * Update StWindow position according to native parent position. */ void StWindowImpl::updateChildRect() { if(!attribs.IsFullScreen && myParentWin != NULL) { //myRectNorm.right() = myRectNorm.left() + widthReturn; //myRectNorm.bottom() = myRectNorm.top() + heightReturn; // update only when changes if(myRectNorm != myRectNormPrev) { myRectNormPrev = myRectNorm; myIsUpdated = true; const StRectI_t& aRect = attribs.IsFullScreen ? myRectFull : myRectNorm; myStEvent.Size.init(getEventTime(), aRect.width(), aRect.height(), myForcedAspect); signals.onResize->emit(myStEvent.Size); } } }
void StWindowImpl::setFullScreen(bool theFullscreen) { if(attribs.IsFullScreen != theFullscreen) { attribs.IsFullScreen = theFullscreen; if(attribs.IsFullScreen) { myFullScreenWinNb.increment(); } else { myFullScreenWinNb.decrement(); } } if(attribs.IsHidden) { // TODO (Kirill Gavrilov#9) parse correctly // do nothing, just set the flag return; } else if(myMaster.stXDisplay.isNull()) { return; } Display* hDisplay = myMaster.stXDisplay->hDisplay; if(attribs.IsFullScreen) { const StMonitor& stMon = (myMonMasterFull == -1) ? myMonitors[myRectNorm.center()] : myMonitors[myMonMasterFull]; myRectFull = stMon.getVRect(); XUnmapWindow(hDisplay, myMaster.hWindowGl); // workaround for strange bugs StRectI_t aRect = myRectFull; // use tiled Master+Slave layout within single window if possible if(attribs.Slave != StWinSlave_slaveOff && isSlaveIndependent() && myMonitors.size() > 1) { StRectI_t aRectSlave; aRectSlave.left() = getSlaveLeft(); aRectSlave.top() = getSlaveTop(); aRectSlave.right() = aRectSlave.left() + myRectFull.width(); aRectSlave.bottom() = aRectSlave.top() + myRectFull.height(); myTiledCfg = TiledCfg_Separate; if(myRectFull.top() == aRectSlave.top()) { if(myRectFull.right() == aRectSlave.left()) { myTiledCfg = TiledCfg_MasterSlaveX; } else if(myRectFull.left() == aRectSlave.right()) { myTiledCfg = TiledCfg_SlaveMasterX; } } else if(myRectFull.left() == aRectSlave.left()) { if(myRectFull.bottom() == aRectSlave.top()) { myTiledCfg = TiledCfg_MasterSlaveY; } else if(myRectFull.top() == aRectSlave.bottom()) { myTiledCfg = TiledCfg_SlaveMasterY; } } } if(myTiledCfg != TiledCfg_Separate) { XUnmapWindow(hDisplay, mySlave.hWindowGl); getTiledWinRect(aRect); } else if(attribs.Split == StWinSlave_splitHorizontal) { myTiledCfg = TiledCfg_MasterSlaveX; myRectFull.right() -= myRectFull.width() / 2; } else if(attribs.Split == StWinSlave_splitVertical) { myTiledCfg = TiledCfg_MasterSlaveY; myRectFull.bottom() -= myRectFull.height() / 2; } if((Window )myParentWin != 0 || myMaster.hWindow != 0) { XReparentWindow(hDisplay, myMaster.hWindowGl, myMaster.stXDisplay->getRootWindow(), 0, 0); XMoveResizeWindow(hDisplay, myMaster.hWindowGl, aRect.left(), aRect.top(), aRect.width(), aRect.height()); XFlush(hDisplay); XMapWindow(hDisplay, myMaster.hWindowGl); //XIfEvent(hDisplay, &myXEvent, stXWaitMapped, (char* )myMaster.hWindowGl); } else { XMoveResizeWindow(hDisplay, myMaster.hWindowGl, aRect.left(), aRect.top(), aRect.width(), aRect.height()); XFlush(hDisplay); XMapWindow(hDisplay, myMaster.hWindowGl); //XIfEvent(hDisplay, &myXEvent, stXWaitMapped, (char* )myMaster.hWindowGl); } if(attribs.Slave != StWinSlave_slaveOff && myTiledCfg == TiledCfg_Separate && (!isSlaveIndependent() || myMonitors.size() > 1)) { XMoveResizeWindow(hDisplay, mySlave.hWindowGl, getSlaveLeft(), getSlaveTop(), getSlaveWidth(), getSlaveHeight()); } } else { Window aParent = ((Window )myParentWin != 0) ? (Window )myParentWin : myMaster.hWindow; if(aParent != 0) { // workaround bugs in some OpenGL drivers (Catalyst etc.) - entirely re-create window but not GL context XSetWindowAttributes aWinAttribsX = createDefaultAttribs(myMaster.stXDisplay); aWinAttribsX.override_redirect = True; // GL window always undecorated Window aWin = XCreateWindow(hDisplay, aParent, 0, 0, myRectNorm.width(), myRectNorm.height(), 0, myMaster.stXDisplay->getDepth(), InputOutput, myMaster.stXDisplay->getVisual(), CWBorderPixel | CWColormap | CWEventMask | CWOverrideRedirect, &aWinAttribsX); #if defined(ST_HAVE_EGL) EGLSurface anEglSurf = eglCreateWindowSurface(myMaster.hRC->getDisplay(), myMaster.hRC->getConfig(), aWin, NULL); if(anEglSurf == EGL_NO_SURFACE || !myMaster.hRC->makeCurrent(anEglSurf)) { if(anEglSurf == EGL_NO_SURFACE) { eglDestroySurface(myMaster.hRC->getDisplay(), anEglSurf); } #else if(!myMaster.hRC->makeCurrent(aWin)) { #endif ST_ERROR_LOG("X, FAILED to bind rendering context to NEW master window"); XDestroyWindow(hDisplay, aWin); XReparentWindow(hDisplay, myMaster.hWindowGl, aParent, 0, 0); } else { XUnmapWindow (hDisplay, myMaster.hWindowGl); XDestroyWindow(hDisplay, myMaster.hWindowGl); myMaster.hWindowGl = aWin; #if defined(ST_HAVE_EGL) eglDestroySurface(myMaster.hRC->getDisplay(), myMaster.eglSurface); myMaster.eglSurface = anEglSurf; #endif XSetStandardProperties(hDisplay, myMaster.hWindowGl, "master window", "master window", None, NULL, 0, NULL); myMaster.setupXDND(); if(attribs.ToHideCursor) { myMaster.setupNoCursor(); } XMapWindow(hDisplay, myMaster.hWindowGl); } myIsUpdated = true; } else { XUnmapWindow(hDisplay, myMaster.hWindowGl); // workaround for strange bugs XResizeWindow(hDisplay, myMaster.hWindowGl, 256, 256); if(attribs.Slave != StWinSlave_slaveOff && (!isSlaveIndependent() || myMonitors.size() > 1)) { XUnmapWindow (hDisplay, mySlave.hWindowGl); XResizeWindow(hDisplay, mySlave.hWindowGl, 256, 256); } XFlush(hDisplay); XMapWindow(hDisplay, myMaster.hWindowGl); //XIfEvent(hDisplay, &myXEvent, stXWaitMapped, (char* )myMaster.hWindowGl); if(attribs.Slave != StWinSlave_slaveOff && (!isSlaveIndependent() || myMonitors.size() > 1)) { XMapWindow(hDisplay, mySlave.hWindowGl); //XIfEvent(hDisplay, &myXEvent, stXWaitMapped, (char* )mySlave.hWindowGl); } XFlush(hDisplay); XMoveResizeWindow(hDisplay, myMaster.hWindowGl, myRectNorm.left(), myRectNorm.top(), myRectNorm.width(), myRectNorm.height()); } } XSetInputFocus(hDisplay, myMaster.hWindowGl, RevertToParent, CurrentTime); const StRectI_t& aRect = attribs.IsFullScreen ? myRectFull : myRectNorm; myStEvent.Type = stEvent_Size; myStEvent.Size.Time = getEventTime(); myStEvent.Size.SizeX = aRect.width(); myStEvent.Size.SizeY = aRect.height(); signals.onResize->emit(myStEvent.Size); // flushes the output buffer, most client apps needn't use this cause buffer is automatically flushed as needed by calls to XNextEvent()... XFlush(hDisplay); } void StWindowImpl::parseXDNDClientMsg() { const StXDisplayH& aDisplay = myMaster.stXDisplay; // myMaster.hWindow or myMaster.hWindowGl Window aWinReciever = ((XClientMessageEvent* )&myXEvent)->window; if(myXEvent.xclient.message_type == aDisplay->xDNDEnter) { myMaster.xDNDVersion = (myXEvent.xclient.data.l[1] >> 24); bool isMoreThan3 = myXEvent.xclient.data.l[1] & 1; Window aSrcWin = myXEvent.xclient.data.l[0]; /*ST_DEBUG_LOG( "Xdnd: Source window = 0x" + (int )myXEvent.xclient.data.l[0] + "\n" + "Supports > 3 types = " + (more_than_3) + "\n" + "Protocol version = " + myMaster.xDNDVersion + "\n" + "Type 1 = " + myMaster.getAtomName(myXEvent.xclient.data.l[2]) + "\n" + "Type 2 = " + myMaster.getAtomName(myXEvent.xclient.data.l[3]) + "\n" + "Type 3 = " + myMaster.getAtomName(myXEvent.xclient.data.l[4]) + "\n" );*/ if(isMoreThan3) { Property aProperty = aDisplay->readProperty(aSrcWin, aDisplay->xDNDTypeList); Atom* anAtomList = (Atom* )aProperty.data; for(int anIter = 0; anIter < aProperty.nitems; ++anIter) { if(anAtomList[anIter] == aDisplay->xDNDUriList) { myMaster.xDNDRequestType = aDisplay->xDNDUriList; break; } else if(anAtomList[anIter] == aDisplay->xDNDPlainText) { myMaster.xDNDRequestType = aDisplay->xDNDPlainText; break; } } XFree(aProperty.data); } else if((Atom )myXEvent.xclient.data.l[2] == aDisplay->xDNDPlainText || (Atom )myXEvent.xclient.data.l[3] == aDisplay->xDNDPlainText || (Atom )myXEvent.xclient.data.l[4] == aDisplay->xDNDPlainText) { myMaster.xDNDRequestType = aDisplay->xDNDPlainText; } else { myMaster.xDNDRequestType = XA_STRING; } } else if(myXEvent.xclient.message_type == aDisplay->xDNDPosition) {
void StWindowImpl::processEvents() { if(myParentWin == NULL || myToResetDevice) { // window is closed! return; } // check if we are exiting if(myParentWin->ToDestroy()) { myStEvent.Type = stEvent_Close; myStEvent.Close.Time = getEventTime(); signals.onClose->emit(myStEvent.Close); return; } // check onNewIntent event StString aDndFile; myParentWin->setHardwareStereoOn(myToEnableStereoHW); myParentWin->setTrackOrientation(myToTrackOrient); myParentWin->setHideSystemBars(myToHideStatusBar, myToHideNavBar); myParentWin->fetchState(aDndFile, myQuaternion, myToSwapEyesHW, myKeysState); if(!aDndFile.isEmpty()) { std::vector<const char*> aDndList; aDndList.push_back(aDndFile.toCString()); myStEvent.Type = stEvent_FileDrop; myStEvent.DNDrop.Time = getEventTime(); myStEvent.DNDrop.NbFiles = aDndList.size(); myStEvent.DNDrop.Files = &aDndList[0]; myEventsBuffer.append(myStEvent); } updateActiveState(); StPointD_t anOldMousePt = myMousePt; int aPollRes = 0; int aNbEvents = 0; StAndroidPollSource* aSource = NULL; bool toWaitEvents = false; while((aPollRes = ALooper_pollAll(toWaitEvents ? -1 : 0, NULL, &aNbEvents, (void** )&aSource)) >= 0) { if(aSource != NULL) { aSource->process(myParentWin, aSource); } if(myToResetDevice) { break; } // check if we are exiting if(myParentWin->ToDestroy()) { break; } } // check if we are exiting if(myParentWin->ToDestroy()) { myStEvent.Type = stEvent_Close; myStEvent.Close.Time = getEventTime(); signals.onClose->emit(myStEvent.Close); return; } myIsMouseMoved = false; if(myMousePt.x() >= 0.0 && myMousePt.x() <= 1.0 && myMousePt.y() >= 0.0 && myMousePt.y() <= 1.0) { StPointD_t aDspl = myMousePt - anOldMousePt; if(std::abs(aDspl.x()) >= 0.0008 || std::abs(aDspl.y()) >= 0.0008) { myIsMouseMoved = true; } } // update position only when all messages are parsed updateWindowPos(); myIsUpdated = false; // StWindow XLib implementation process events in the same thread // thus this double buffer is not in use // however user events may be posted to it swapEventsBuffers(); }
bool StWindowImpl::onAndroidInitWindow() { myIsPaused = false; if(myParentWin->getWindow() == NULL) { return false; } if(!myMaster.hRC.isNull()) { myMaster.hWindowGl = myParentWin->getWindow(); EGLint anEglErr = eglGetError(); (void )anEglErr; EGLint aFormat = 0; if(eglGetConfigAttrib(myMaster.hRC->getDisplay(), myMaster.hRC->getConfig(), EGL_NATIVE_VISUAL_ID, &aFormat) == EGL_FALSE) { anEglErr = eglGetError(); } ANativeWindow_setBuffersGeometry(myMaster.hWindowGl, 0, 0, aFormat); myMaster.eglSurface = eglCreateWindowSurface(myMaster.hRC->getDisplay(), myMaster.hRC->getConfig(), myMaster.hWindowGl, NULL); if(myMaster.eglSurface == NULL) { anEglErr = eglGetError(); } // bind the rendering context to the window if(!myMaster.hRC->makeCurrent(myMaster.eglSurface)) { myMaster.close(); mySlave.close(); myInitState = STWIN_ERROR_X_GLRC_CREATE; stError("Critical error - broken EGL context!"); return false; } const EGLint aWidth = ANativeWindow_getWidth (myMaster.hWindowGl); const EGLint aHeight = ANativeWindow_getHeight(myMaster.hWindowGl); const bool isResized = myRectNorm.width() != aWidth || myRectNorm.height() != aHeight; myRectNorm.left() = 0; myRectNorm.top() = 0; myRectNorm.right() = myRectNorm.left() + aWidth; myRectNorm.bottom() = myRectNorm.top() + aHeight; myRectFull = myRectNorm; myInitState = STWIN_INIT_SUCCESS; if(isResized) { myStEvent.Size.init(getEventTime(), myRectNorm.width(), myRectNorm.height(), myForcedAspect); signals.onResize->emit(myStEvent.Size); } return true; } myMaster.hRC = new StWinGlrc(eglGetDisplay(EGL_DEFAULT_DISPLAY), attribs.IsGlDebug, attribs.GlDepthSize, attribs.GlStencilSize); if(!myMaster.hRC->isValid()) { myMaster.close(); mySlave.close(); myInitState = STWIN_ERROR_X_GLRC_CREATE; return false; } myMaster.hWindowGl = myParentWin->getWindow(); myInitState = myMaster.glCreateContext(NULL, myRectNorm, attribs.GlDepthSize, attribs.GlStencilSize, attribs.IsGlStereo, attribs.IsGlDebug); if(myInitState != STWIN_INIT_SUCCESS) { return false; } EGLint aWidth = 0, aHeight = 0; if(myMaster.hWindowGl != NULL) { aWidth = ANativeWindow_getWidth (myMaster.hWindowGl); aHeight = ANativeWindow_getHeight(myMaster.hWindowGl); } else if(myMaster.eglSurface != EGL_NO_SURFACE) { eglQuerySurface(myMaster.hRC->getDisplay(), myMaster.eglSurface, EGL_WIDTH, &aWidth); eglQuerySurface(myMaster.hRC->getDisplay(), myMaster.eglSurface, EGL_HEIGHT, &aHeight); } myRectNorm.left() = 0; myRectNorm.top() = 0; myRectNorm.right() = myRectNorm.left() + aWidth; myRectNorm.bottom() = myRectNorm.top() + aHeight; myRectFull = myRectNorm; myGlContext = new StGLContext(myResMgr); if(!myGlContext->stglInit()) { myMaster.close(); mySlave.close(); stError("Critical error - broken GL context!\nInvalid OpenGL driver?"); myInitState = STWIN_ERROR_X_GLRC_CREATE; return false; } myInitState = STWIN_INIT_SUCCESS; return true; }
void StWindowImpl::onAndroidInput(const AInputEvent* theEvent, bool& theIsProcessed) { const int anEventType = AInputEvent_getType(theEvent); switch(anEventType) { case AINPUT_EVENT_TYPE_KEY: { StVirtKey aVKeySt = ST_VK_NULL; int32_t aKeySym = AKeyEvent_getKeyCode(theEvent); if(aKeySym < ST_ANDROID2ST_VK_SIZE) { aVKeySt = (StVirtKey )ST_ANDROID2ST_VK[aKeySym]; } if(aVKeySt == ST_VK_NULL) { return; } myStEvent.Key.Time = getEventTime(); //AKeyEvent_getEventTime(theEvent); myStEvent.Key.VKey = aVKeySt; myStEvent.Key.Char = 0; const int32_t aKeyAction = AKeyEvent_getAction(theEvent); if(aKeyAction == AKEY_EVENT_ACTION_DOWN) { postKeyDown(myStEvent); } else if(aKeyAction == AKEY_EVENT_ACTION_UP) { postKeyUp(myStEvent); }// else if(aKeyAction == AKEY_EVENT_ACTION_MULTIPLE) {} return; } case AINPUT_EVENT_TYPE_MOTION: { theIsProcessed = true; const int32_t aSource = AInputEvent_getSource(theEvent); const int32_t anActionPak = AMotionEvent_getAction(theEvent); const int32_t anAction = anActionPak & AMOTION_EVENT_ACTION_MASK; const size_t anActionPntIndex = anActionPak & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK; //const StRectI_t& aWinRect = attribs.IsFullScreen ? myRectFull : myRectNorm; const StRectI_t& aWinRect = myRectNorm; const float aWinSizeX = aWinRect.width(); const float aWinSizeY = aWinRect.height(); // at least single point is defined StPointD_t aPos0(double(AMotionEvent_getX(theEvent, 0)) / double(aWinSizeX), double(AMotionEvent_getY(theEvent, 0)) / double(aWinSizeY)); myStEvent.Type = stEvent_None; myStEvent.Base.Time = getEventTime(); /// int64_t AMotionEvent_getEventTime(theEvent); switch(aSource) { case AINPUT_SOURCE_TOUCHSCREEN: case AINPUT_SOURCE_TOUCHPAD: { const size_t aNbTouches = AMotionEvent_getPointerCount(theEvent); myStEvent.Touch.NbTouches = std::min(aNbTouches, (size_t )ST_MAX_TOUCHES); bool isUp = anAction == AMOTION_EVENT_ACTION_UP || anAction == AMOTION_EVENT_ACTION_POINTER_UP; if(isUp) { myStEvent.Touch.NbTouches = std::max(myStEvent.Touch.NbTouches - 1, 0); } for(size_t aTouchIter = 0; aTouchIter < ST_MAX_TOUCHES; ++aTouchIter) { StTouch& aTouch = myStEvent.Touch.Touches[aTouchIter]; aTouch = StTouch::Empty(); if(aTouchIter == anActionPntIndex && isUp) { continue; } if(aTouchIter >= aNbTouches) { continue; } aTouch.Id = AMotionEvent_getPointerId(theEvent, aTouchIter); aTouch.DeviceId = AInputEvent_getDeviceId(theEvent); aTouch.OnScreen = aSource == AINPUT_SOURCE_TOUCHSCREEN; const float aPosX = AMotionEvent_getX(theEvent, aTouchIter); const float aPosY = AMotionEvent_getY(theEvent, aTouchIter); aTouch.PointX = (aPosX - float(aWinRect.left())) / aWinSizeX; aTouch.PointY = (aPosY - float(aWinRect.top())) / aWinSizeY; } switch(anAction) { case AMOTION_EVENT_ACTION_DOWN: case AMOTION_EVENT_ACTION_POINTER_DOWN: { myStEvent.Type = stEvent_TouchDown; doTouch(myStEvent.Touch); if(aNbTouches == 1) { // simulate mouse click myMousePt = aPos0; myIsPreciseCursor = false; myStEvent.Type = stEvent_MouseDown; myStEvent.Button.Button = ST_MOUSE_LEFT; myStEvent.Button.Buttons = 0; myStEvent.Button.PointX = myMousePt.x(); myStEvent.Button.PointY = myMousePt.y(); signals.onMouseDown->emit(myStEvent.Button); } else if(aNbTouches == 2) { // emit special event to cancel previously simulated click myStEvent.Type = stEvent_MouseCancel; myStEvent.Button.Button = ST_MOUSE_LEFT; myStEvent.Button.Buttons = 0; myStEvent.Button.PointX = myMousePt.x(); myStEvent.Button.PointY = myMousePt.y(); signals.onMouseUp->emit(myStEvent.Button); } break; } case AMOTION_EVENT_ACTION_MOVE: { myStEvent.Type = stEvent_TouchMove; if(aNbTouches == 1) { // simulate mouse move myMousePt = aPos0; myIsPreciseCursor = false; } doTouch(myStEvent.Touch); break; } case AMOTION_EVENT_ACTION_UP: case AMOTION_EVENT_ACTION_POINTER_UP: { myStEvent.Type = stEvent_TouchUp; doTouch(myStEvent.Touch); if(aNbTouches == 1) { // simulate mouse unclick myMousePt = aPos0; myIsPreciseCursor = false; myStEvent.Type = stEvent_MouseUp; myStEvent.Button.Button = ST_MOUSE_LEFT; myStEvent.Button.Buttons = 0; myStEvent.Button.PointX = myMousePt.x(); myStEvent.Button.PointY = myMousePt.y(); signals.onMouseUp->emit(myStEvent.Button); } break; } case AMOTION_EVENT_ACTION_CANCEL: { myStEvent.Type = stEvent_TouchCancel; doTouch(myStEvent.Touch); break; } } return; } } myMousePt = aPos0; myIsPreciseCursor = aSource == AINPUT_SOURCE_MOUSE; // || AINPUT_SOURCE_STYLUS StVirtButton aMouseBtn = ST_MOUSE_LEFT; myStEvent.Button.Button = aMouseBtn; myStEvent.Button.Buttons = 0; myStEvent.Button.PointX = myMousePt.x(); myStEvent.Button.PointY = myMousePt.y(); if(anAction == AMOTION_EVENT_ACTION_DOWN) { myStEvent.Type = stEvent_MouseDown; signals.onMouseDown->emit(myStEvent.Button); } else if(anAction == AMOTION_EVENT_ACTION_UP) { myStEvent.Type = stEvent_MouseUp; signals.onMouseUp->emit(myStEvent.Button); } return; } } }
//============================================================================== double MidiMessageSequence::getStartTime() const noexcept { return getEventTime (0); }
void StWindowImpl::onAndroidCommand(int32_t theCommand) { switch(theCommand) { case StAndroidGlue::CommandId_SaveState: { // the system has asked us to save our current state /*StSavedState* aState = (StSavedState* )malloc(sizeof(StSavedState)); *aState = state; myParentWin->setSavedState(aState, sizeof(StSavedState));*/ return; } case StAndroidGlue::CommandId_WindowInit: { // the window is being shown, get it ready onAndroidInitWindow(); return; } case StAndroidGlue::CommandId_BackPressed: { myStEvent.Key.Time = getEventTime(); myStEvent.Key.VKey = ST_VK_ESCAPE; myStEvent.Key.Char = 0; postKeyDown(myStEvent); postKeyUp (myStEvent); return; } case StAndroidGlue::CommandId_Resume: { myIsPaused = false; return; } case StAndroidGlue::CommandId_Pause: { myIsPaused = true; myStEvent.Type = stEvent_Pause; myStEvent.Pause.Time = getEventTime(); signals.onPause->emit(myStEvent.Pause); return; } case StAndroidGlue::CommandId_Stop: { if(myParentWin->getMemoryClass() < 50) { myStEvent.Type = stEvent_Close; myStEvent.Close.Time = getEventTime(); signals.onClose->emit(myStEvent.Close); } break; } case StAndroidGlue::CommandId_WindowChanged: case StAndroidGlue::CommandId_WindowTerm: { if(!myMaster.hRC.isNull()) { myMaster.hRC->makeCurrent(EGL_NO_SURFACE); if(myMaster.eglSurface != EGL_NO_SURFACE) { eglDestroySurface(myMaster.hRC->getDisplay(), myMaster.eglSurface); myMaster.eglSurface = EGL_NO_SURFACE; } } myMaster.hWindowGl = NULL; if(theCommand == StAndroidGlue::CommandId_WindowChanged) { onAndroidInitWindow(); } return; } case StAndroidGlue::CommandId_FocusGained: { // return; } case StAndroidGlue::CommandId_FocusLost: { myKeysState.reset(); return; } case StAndroidGlue::CommandId_ConfigChanged: { // do not handle resize event here - screen might be not yet resized updateMonitors(); myStEvent.Size.init(getEventTime(), myRectNorm.width(), myRectNorm.height(), myForcedAspect); myStEvent.Type = stEvent_NewMonitor; //myWinOnMonitorId = 0; signals.onAnotherMonitor->emit(myStEvent.Size); return; } } }
double MidiMessageSequence::getEndTime() const noexcept { return getEventTime (list.size() - 1); }
//************************************************************************** void control_inst_t::Retire( abstract_pc_t *a ) { #ifdef DEBUG_DYNAMIC_RET DEBUG_OUT("control_inst_t:Retire BEGIN, proc[%d]\n",m_proc); #endif #ifdef DEBUG_DYNAMIC char buf[128]; s->printDisassemble(buf); DEBUG_OUT("\tcontrol_inst_t::Retire BEGIN %s seq_num[ %lld ] cycle[ %lld ] fetchPC[ 0x%llx ] fetchNPC[ 0x%llx ] PredictedPC[ 0x%llx ] PredictedNPC[ 0x%llx ]\n", buf, seq_num, m_pseq->getLocalCycle(), m_actual.pc, m_actual.npc, m_predicted.pc, m_predicted.npc); for(int i=0; i < SI_MAX_DEST; ++i){ reg_id_t & dest = getDestReg(i); reg_id_t & tofree = getToFreeReg(i); if( !dest.isZero() ){ DEBUG_OUT("\tDest[ %d ] Vanilla[ %d ] Physical[ %d ] Arf[ %s ] ToFree: Vanilla[ %d ] physical[ %d ] Arf[ %s ]\n", i, dest.getVanilla(), dest.getPhysical(), dest.rid_type_menomic( dest.getRtype() ), tofree.getVanilla(), tofree.getPhysical(), tofree.rid_type_menomic( tofree.getRtype() ) ); } } #endif ASSERT( !getEvent( EVENT_FINALIZED ) ); STAT_INC( m_pseq->m_stat_control_retired[m_proc] ); // Need this bc we place fetch barrier on retry instead of stxa: if ( (s->getOpcode() == i_retry) || (s->getFlag( SI_FETCH_BARRIER)) ) { // if we have a branch misprediction, we already unstalled the fetch in partialSquash(): if(getEvent(EVENT_BRANCH_MISPREDICT) == false){ m_pseq->unstallFetch(m_proc); } } STAT_INC( m_pseq->m_branch_seen_stat[s->getBranchType()][2] ); STAT_INC( m_pseq->m_branch_seen_stat[s->getBranchType()][m_priv? 1:0] ); // record when execution takes place m_event_times[EVENT_TIME_RETIRE] = m_pseq->getLocalCycle() - m_fetch_cycle; // update dynamic branch prediction (predicated) instruction statistics static_inst_t *s_instr = getStaticInst(); if (s_instr->getType() == DYN_CONTROL) { uint32 inst; int op2; int pred; switch (s_instr->getBranchType()) { case BRANCH_COND: // conditional branch STAT_INC( m_pseq->m_nonpred_retire_count_stat[m_proc] ); break; case BRANCH_PCOND: // predictated conditional inst = s_instr->getInst(); op2 = maskBits32( inst, 22, 24 ); pred = maskBits32( inst, 19, 19 ); if ( op2 == 3 ) { // integer register w/ predication STAT_INC( m_pseq->m_pred_reg_retire_count_stat[m_proc] ); if (pred) { STAT_INC( m_pseq->m_pred_reg_retire_taken_stat[m_proc] ); } else { STAT_INC( m_pseq->m_pred_reg_retire_nottaken_stat[m_proc] ); } } else { STAT_INC( m_pseq->m_pred_retire_count_stat[m_proc] ); if (pred) { STAT_INC( m_pseq->m_pred_retire_count_taken_stat[m_proc] ); } else { STAT_INC( m_pseq->m_pred_retire_count_nottaken_stat[m_proc] ); } } if (pred == true && m_isTaken == false || pred == false && m_isTaken == true) { STAT_INC( m_pseq->m_branch_wrong_static_stat ); } break; default: ; // ignore non-predictated branches } } #ifdef DEBUG_RETIRE m_pseq->out_info("## Control Retire Stage\n"); printDetail(); m_pseq->printPC( &m_actual ); #endif bool mispredict = (m_events & EVENT_BRANCH_MISPREDICT); if (mispredict) { // incorrect branch prediction STAT_INC( m_pseq->m_branch_wrong_stat[s->getBranchType()][2] ); STAT_INC( m_pseq->m_branch_wrong_stat[s->getBranchType()][m_priv? 1:0] ); //train BRANCH_PRIV predictor if( (s->getBranchType() == BRANCH_PRIV) ){ if (m_predicted.cwp != m_actual.cwp) { m_pseq->getRegstatePred()->update(getVPC(), CONTROL_CWP, m_actual.cwp, m_predicted.cwp); } if (m_predicted.tl != m_actual.tl) { m_pseq->getRegstatePred()->update(getVPC(), CONTROL_TL, m_actual.tl, m_predicted.tl); } if (m_predicted.pstate != m_actual.pstate) { m_pseq->getRegstatePred()->update(getVPC(), CONTROL_PSTATE, m_actual.pstate, m_predicted.pstate); } } //****************************** print out mispredicted inst ***************** if(s->getBranchType() == BRANCH_PRIV){ char buf[128]; s->printDisassemble( buf ); bool imm = s->getFlag(SI_ISIMMEDIATE); #if 0 if(m_predicted.pc != m_actual.pc){ m_pseq->out_info("CONTROLOP: PC mispredict: predicted[ 0x%llx ] actual[ 0x%llx ] type=%s seqnum[ %lld ] VPC[ 0x%llx ] PC[ 0x%llx ] fetched[ %lld ] executed[ %lld ] correctPC[ 0x%llx ] imm[ %d ] %s\n", m_predicted.pc, m_actual.pc, pstate_t::branch_type_menomic[s->getBranchType()], seq_num, getVPC(), getPC(), m_fetch_cycle, m_event_times[EVENT_TIME_EXECUTE] + m_fetch_cycle, m_actual.pc, imm, buf); } #endif #if 0 if(m_predicted.npc != m_actual.npc){ m_pseq->out_info("CONTROLOP: NPC mispredict: predicted[ 0x%llx ] actual[ 0x%llx ] type=%s seqnum[ %lld ] VPC[ 0x%llx ] PC[ 0x%llx ] fetched[ %lld ] executed[ %lld ] correctPC[ 0x%llx ] imm[ %d ] %s\n", m_predicted.npc, m_actual.npc, pstate_t::branch_type_menomic[s->getBranchType()], seq_num, getVPC(), getPC(), m_fetch_cycle, m_event_times[EVENT_TIME_EXECUTE] + m_fetch_cycle, m_actual.pc, imm, buf); } #endif #if 0 if (m_predicted.cwp != m_actual.cwp) { m_pseq->out_info("CONTROLOP: CWP mispredict: predicted[ %d ] actual[ %d ] type=%s seqnum[ %lld ] VPC[ 0x%llx ] PC[ 0x%llx ] fetched[ %lld ] executed[ %lld ] correctPC[ 0x%llx ] imm[ %d ] %s\n", m_predicted.cwp, m_actual.cwp, pstate_t::branch_type_menomic[s->getBranchType()], seq_num, getVPC(), getPC(), m_fetch_cycle, m_event_times[EVENT_TIME_EXECUTE] + m_fetch_cycle, m_actual.pc, imm, buf); } #endif #if 0 if (m_predicted.tl != m_actual.tl) { m_pseq->out_info("CONTROLOP: TL mispredict: predicted[ %d ] actual[ %d ] type=%s seqnum[ %lld ] VPC[ 0x%llx ] PC[ 0x%llx ] fetched[ %lld ] executed[ %lld ] correctPC[ 0x%llx ] imm[ %d ] %s\n", m_predicted.tl, m_actual.tl, pstate_t::branch_type_menomic[s->getBranchType()], seq_num, getVPC(), getPC(), m_fetch_cycle, m_event_times[EVENT_TIME_EXECUTE] + m_fetch_cycle, m_actual.pc, imm, buf); } #endif #if 0 if (m_predicted.pstate != m_actual.pstate) { m_pseq->out_info("CONTROLOP: PSTATE mispredict: predicted[ 0x%0x ] actual[ 0x%0x ] type=%s seqnum[ %lld ] VPC[ 0x%llx ] PC[ 0x%llx ] fetched[ %lld ] executed[ %lld ] correctPC[ 0x%llx ] imm[ %d ] %s\n", m_predicted.pstate, m_actual.pstate, pstate_t::branch_type_menomic[s->getBranchType()], seq_num, getVPC(), getPC(), m_fetch_cycle, m_event_times[EVENT_TIME_EXECUTE] + m_fetch_cycle, m_actual.pc, imm, buf); } #endif } //************************************************************************** // train ras's exception table if (ras_t::EXCEPTION_TABLE && s->getBranchType() == BRANCH_RETURN) { my_addr_t tos; ras_t *ras = m_pseq->getRAS(m_proc); ras->getTop(&(m_pred_state.ras_state), &tos); if(tos == m_actual.npc) { ras->markException(m_predicted.npc); // update RAS state ras->pop(&(m_pred_state.ras_state)); m_pseq->setSpecBPS(m_pred_state); if (ras_t::DEBUG_RAS) m_pseq->out_info("*********** DEBUG_RAS ***********\n"); } else { ras->unmarkException(m_actual.npc); } } // XU DEBUG if (0 && s->getBranchType() == BRANCH_RETURN) { m_pseq->out_info("**** %c:mispred 0x%llx, pred 0x%llx target 0x%llx, " "next %d TOS %d\n", m_priv? 'K':'U', getVPC(), m_predicted.npc, m_actual.npc, m_pred_state.ras_state.next_free, m_pred_state.ras_state.TOS); // print 5 instr after mis-pred generic_address_t addr = m_predicted.npc-8; for(uint32 i = 0; i < 5; i++, addr+=4) { //get the actual seq number for the pointer to m_state: int32 seq_num = m_pseq->getID() / CONFIG_LOGICAL_PER_PHY_PROC; assert(seq_num >= 0 && seq_num < system_t::inst->m_numSMTProcs); tuple_int_string_t *disassemble = SIM_disassemble((processor_t *) system_t::inst->m_state[seq_num]->getSimicsProcessor(m_proc), addr, /* logical */ 1); if (disassemble) m_pseq->out_info(" %s\n", disassemble->string); } } } else { // correct or no prediction STAT_INC( m_pseq->m_branch_right_stat[s->getBranchType()][2] ); STAT_INC( m_pseq->m_branch_right_stat[s->getBranchType()][m_priv? 1:0] ); } /* update branch predictor tables at retirement */ if (s->getBranchType() == BRANCH_COND || s->getBranchType() == BRANCH_PCOND) { m_pseq->getDirectBP()->Update(getVPC(), (m_pseq->getArchBPS()->cond_state), s->getFlag( SI_STATICPRED ), m_isTaken, m_proc); } else if (s->getBranchType() == BRANCH_INDIRECT || (s->getBranchType() == BRANCH_CALL && s->getOpcode() != i_call) ) { // m_actual.npc is the indirect target m_pseq->getIndirectBP()->Update( getVPC(), &(m_pseq->getArchBPS()->indirect_state), m_actual.npc, m_proc ); } m_pseq->setArchBPS(m_pred_state); // no need to update call&return, since we used checkpointed RAS // no update on traps right now SetStage(RETIRE_STAGE); /* retire any register overwritten by link register */ retireRegisters(); #if 0 if(m_actual.pc == (my_addr_t) -1){ char buf[128]; s->printDisassemble(buf); ERROR_OUT("\tcontrol_inst_t::Retire %s seq_num[ %lld ] cycle[ %lld ] fetchPC[ 0x%llx ] fetchNPC[ 0x%llx ] fetched[ %lld ] executed[ %lld ]\n", buf, seq_num, m_pseq->getLocalCycle(), m_actual.pc, m_actual.npc, m_fetch_cycle, m_fetch_cycle+getEventTime(EVENT_TIME_EXECUTE_DONE)); //print out writer cycle for(int i=0; i < SI_MAX_SOURCE; ++i){ reg_id_t & source = getSourceReg(i); if(!source.isZero()){ uint64 written_cycle = source.getARF()->getWrittenCycle( source, m_proc ); uint64 writer_seqnum = source.getARF()->getWriterSeqnum( source, m_proc ); ERROR_OUT("\tSource[ %d ] Vanilla[ %d ] Physical[ %d ] Arf[ %s ] written_cycle[ %lld ] writer_seqnum[ %lld ]\n", i, source.getVanilla(), source.getPhysical(), source.rid_type_menomic( source.getRtype() ), written_cycle, writer_seqnum); } } } #endif ASSERT( m_actual.pc != (my_addr_t) -1 ); /* return pc, npc pair which are the results of execution */ a->pc = m_actual.pc; a->npc = m_actual.npc; markEvent( EVENT_FINALIZED ); #ifdef DEBUG_DYNAMIC_RET DEBUG_OUT("control_inst_t:Retire END, proc[%d]\n",m_proc); #endif }