示例#1
0
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"));
    }
}
示例#3
0
    static uint8* findEventAfter (uint8* d, uint8* endData, const int samplePosition) noexcept
    {
        while (d < endData && getEventTime (d) <= samplePosition)
            d += getEventTotalSize (d);

        return d;
    }
示例#4
0
/**
 * 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);
        }
    }
}
示例#5
0
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();
}
示例#6
0
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);
}
示例#7
0
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;
}
示例#8
0
// 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;
}
示例#9
0
/**
 * 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);
        }
    }
}
示例#10
0
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) {
示例#11
0
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();
}
示例#12
0
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;
}
示例#13
0
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;
        }
    }
}
示例#14
0
//==============================================================================
double MidiMessageSequence::getStartTime() const noexcept
{
    return getEventTime (0);
}
示例#15
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;
        }
    }
}
示例#16
0
double MidiMessageSequence::getEndTime() const noexcept
{
    return getEventTime (list.size() - 1);
}
示例#17
0
//**************************************************************************
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
}