예제 #1
0
void Light::tick()
{
  if (NORMAL == modeGet()) return;
  if (waiting()) return;

  if (OFF == stateGet()) on();
  else off();

  wait(interval);
}
예제 #2
0
int DragAndDropService::hostCall(uint32_t u32Function, uint32_t cParms, VBOXHGCMSVCPARM paParms[])
{
    int rc = VINF_SUCCESS;
    if (u32Function == DragAndDropSvc::HOST_DND_SET_MODE)
    {
        if (cParms != 1)
            rc = VERR_INVALID_PARAMETER;
        else if (paParms[0].type != VBOX_HGCM_SVC_PARM_32BIT)
            rc = VERR_INVALID_PARAMETER;
        else
            modeSet(paParms[0].u.uint32);
    }
    else if (modeGet() != VBOX_DRAG_AND_DROP_MODE_OFF)
    {
        rc = m_pManager->addMessage(u32Function, cParms, paParms);
        if (    RT_SUCCESS(rc)
            && !m_clientQueue.isEmpty())
        {
            HGCM::Client *pClient = m_clientQueue.first();
            /* Check if this was a request for getting the next host
             * message. If so, return the message id and the parameter
             * count. The message itself has to be queued. */
            if (pClient->message() == DragAndDropSvc::GUEST_DND_GET_NEXT_HOST_MSG)
            {
                DO(("client is waiting for next host msg\n"));
//              rc = m_pManager->nextMessageInfo(&paParms[0].u.uint32, &paParms[1].u.uint32);
                uint32_t uMsg1;
                uint32_t cParms1;
                rc = m_pManager->nextMessageInfo(&uMsg1, &cParms1);
                if (RT_SUCCESS(rc))
                {
                    pClient->addMessageInfo(uMsg1, cParms1);
                    m_pHelpers->pfnCallComplete(pClient->handle(), rc);
                    m_clientQueue.removeFirst();
                    delete pClient;
                }
                else
                    AssertMsgFailed(("Should not happen!"));
            }
            else
                AssertMsgFailed(("Should not happen!"));
        }
//      else
//          AssertMsgFailed(("Should not happen %Rrc!", rc));
    }

    LogFlowFunc(("rc=%Rrc\n", rc));
    return rc;
}
예제 #3
0
void DragAndDropService::guestCall(VBOXHGCMCALLHANDLE callHandle, uint32_t u32ClientID, void *pvClient, uint32_t u32Function, uint32_t cParms, VBOXHGCMSVCPARM paParms[])
{
    int rc = VINF_SUCCESS;
    LogFlowFunc(("u32ClientID = %d, fn = %d, cParms = %d, pparms = %d\n",
                 u32ClientID, u32Function, cParms, paParms));
//    RTPrintf("u32ClientID = %d, fn = %d, cParms = %d, pparms = %d\n",
//                 u32ClientID, u32Function, cParms, paParms);

    switch (u32Function)
    {
        case DragAndDropSvc::GUEST_DND_GET_NEXT_HOST_MSG:
        {
            DO(("GUEST_DND_GET_NEXT_HOST_MSG\n"));
            if (   cParms != 3
                || paParms[0].type != VBOX_HGCM_SVC_PARM_32BIT /* message */
                || paParms[1].type != VBOX_HGCM_SVC_PARM_32BIT /* parameter count */
                || paParms[2].type != VBOX_HGCM_SVC_PARM_32BIT /* blocking */)
                rc = VERR_INVALID_PARAMETER;
            else
            {
                rc = m_pManager->nextMessageInfo(&paParms[0].u.uint32, &paParms[1].u.uint32);
                if (   RT_FAILURE(rc)
                    && paParms[2].u.uint32) /* Blocking? */
                {
                    m_clientQueue.append(new HGCM::Client(u32ClientID, callHandle, u32Function, cParms, paParms));
                    rc = VINF_HGCM_ASYNC_EXECUTE;
                }
            }
            break;
        }
        case DragAndDropSvc::GUEST_DND_HG_ACK_OP:
        {
            DO(("GUEST_DND_HG_ACK_OP\n"));
            if (   modeGet() != VBOX_DRAG_AND_DROP_MODE_BIDIRECTIONAL
                && modeGet() != VBOX_DRAG_AND_DROP_MODE_HOST_TO_GUEST)
            {
                DO(("=> ignoring!\n"));
                break;
            }

            if (   cParms != 1
                || paParms[0].type != VBOX_HGCM_SVC_PARM_32BIT /* action */)
                rc = VERR_INVALID_PARAMETER;
            else
            {
                DragAndDropSvc::VBOXDNDCBHGACKOPDATA data;
                data.hdr.u32Magic = DragAndDropSvc::CB_MAGIC_DND_HG_ACK_OP;
                paParms[0].getUInt32(&data.uAction);
                if (m_pfnHostCallback)
                    rc = m_pfnHostCallback(m_pvHostData, u32Function, &data, sizeof(data));
//                m_pHelpers->pfnCallComplete(callHandle, rc);
            }
            break;
        }
        case DragAndDropSvc::GUEST_DND_HG_REQ_DATA:
        {
            DO(("GUEST_DND_HG_REQ_DATA\n"));
            if (   modeGet() != VBOX_DRAG_AND_DROP_MODE_BIDIRECTIONAL
                && modeGet() != VBOX_DRAG_AND_DROP_MODE_HOST_TO_GUEST)
            {
                DO(("=> ignoring!\n"));
                break;
            }

            if (   cParms != 1
                || paParms[0].type != VBOX_HGCM_SVC_PARM_PTR /* format */)
                rc = VERR_INVALID_PARAMETER;
            else
            {
                DragAndDropSvc::VBOXDNDCBHGREQDATADATA data;
                data.hdr.u32Magic = DragAndDropSvc::CB_MAGIC_DND_HG_REQ_DATA;
                uint32_t cTmp;
                paParms[0].getPointer((void**)&data.pszFormat, &cTmp);
                if (m_pfnHostCallback)
                    rc = m_pfnHostCallback(m_pvHostData, u32Function, &data, sizeof(data));
//                m_pHelpers->pfnCallComplete(callHandle, rc);
//                if (data.pszFormat)
//                    RTMemFree(data.pszFormat);
//                if (data.pszTmpPath)
//                    RTMemFree(data.pszTmpPath);
            }
            break;
        }
#ifdef VBOX_WITH_DRAG_AND_DROP_GH
        case DragAndDropSvc::GUEST_DND_GH_ACK_PENDING:
        {
            DO(("GUEST_DND_GH_ACK_PENDING\n"));
            if (   modeGet() != VBOX_DRAG_AND_DROP_MODE_BIDIRECTIONAL
                && modeGet() != VBOX_DRAG_AND_DROP_MODE_GUEST_TO_HOST)
            {
                DO(("=> ignoring!\n"));
                break;
            }

            if (   cParms != 3
                || paParms[0].type != VBOX_HGCM_SVC_PARM_32BIT /* defaction */
                || paParms[1].type != VBOX_HGCM_SVC_PARM_32BIT /* allactions */
                || paParms[2].type != VBOX_HGCM_SVC_PARM_PTR   /* format */)
                rc = VERR_INVALID_PARAMETER;
            else
            {
                DragAndDropSvc::VBOXDNDCBGHACKPENDINGDATA data;
                data.hdr.u32Magic = DragAndDropSvc::CB_MAGIC_DND_GH_ACK_PENDING;
                paParms[0].getUInt32(&data.uDefAction);
                paParms[1].getUInt32(&data.uAllActions);
                uint32_t cTmp;
                paParms[2].getPointer((void**)&data.pszFormat, &cTmp);
                if (m_pfnHostCallback)
                    rc = m_pfnHostCallback(m_pvHostData, u32Function, &data, sizeof(data));
            }
            break;
        }
        case DragAndDropSvc::GUEST_DND_GH_SND_DATA:
        {
            DO(("GUEST_DND_GH_SND_DATA\n"));
            if (   modeGet() != VBOX_DRAG_AND_DROP_MODE_BIDIRECTIONAL
                && modeGet() != VBOX_DRAG_AND_DROP_MODE_GUEST_TO_HOST)
            {
                DO(("=> ignoring\n"));
                break;
            }

            if (   cParms != 2
                || paParms[0].type != VBOX_HGCM_SVC_PARM_PTR   /* data */
                || paParms[1].type != VBOX_HGCM_SVC_PARM_32BIT /* size */)
                rc = VERR_INVALID_PARAMETER;
            else
            {
                DragAndDropSvc::VBOXDNDCBSNDDATADATA data;
                data.hdr.u32Magic = DragAndDropSvc::CB_MAGIC_DND_GH_SND_DATA;
                paParms[0].getPointer((void**)&data.pvData, &data.cbData);
                paParms[1].getUInt32(&data.cbAllSize);
                if (m_pfnHostCallback)
                    rc = m_pfnHostCallback(m_pvHostData, u32Function, &data, sizeof(data));
            }
            break;
        }
        case DragAndDropSvc::GUEST_DND_GH_EVT_ERROR:
        {
            DO(("GUEST_DND_GH_EVT_ERROR\n"));
            if (   modeGet() != VBOX_DRAG_AND_DROP_MODE_BIDIRECTIONAL
                && modeGet() != VBOX_DRAG_AND_DROP_MODE_GUEST_TO_HOST)
            {
                DO(("=> ignoring!\n"));
                break;
            }

            if (   cParms != 1
                || paParms[0].type != VBOX_HGCM_SVC_PARM_32BIT /* rc */)
                rc = VERR_INVALID_PARAMETER;
            else
            {
                DragAndDropSvc::VBOXDNDCBEVTERRORDATA data;
                data.hdr.u32Magic = DragAndDropSvc::CB_MAGIC_DND_GH_EVT_ERROR;
                uint32_t rcOp;
                paParms[0].getUInt32(&rcOp);
                data.rc = rcOp;
                if (m_pfnHostCallback)
                    rc = m_pfnHostCallback(m_pvHostData, u32Function, &data, sizeof(data));
            }
            break;
        }
#endif
        default:
        {
            /* All other messages are handled by the DnD manager. */
            rc = m_pManager->nextMessage(u32Function, cParms, paParms);
            /* Check for error. Buffer overflow is allowed. It signals the
             * guest to ask for more data in the next event. */
            if (   RT_FAILURE(rc)
                && rc != VERR_CANCELLED
                && rc != VERR_BUFFER_OVERFLOW) /* Buffer overflow is allowed. */
            {
                m_clientQueue.append(new HGCM::Client(u32ClientID, callHandle, u32Function, cParms, paParms));
                rc = VINF_HGCM_ASYNC_EXECUTE;
            }
            break;
        }
    }
    /* If async execute is requested, we didn't notify the guest about
     * completion. The client is queued into the waiters list and will be
     * notified as soon as a new event is available. */
    if (rc != VINF_HGCM_ASYNC_EXECUTE)
        m_pHelpers->pfnCallComplete(callHandle, rc);
    DO(("guest call: %Rrc\n", rc));
}