VirtualBox

Ignore:
Timestamp:
Jul 5, 2010 12:26:27 PM (14 years ago)
Author:
vboxsync
Message:

Frontends: headless frontend use events now

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Frontends/VBoxHeadless/VBoxHeadless.cpp

    r30580 r30606  
    1818#include <VBox/com/com.h>
    1919#include <VBox/com/string.h>
     20#include <VBox/com/array.h>
    2021#include <VBox/com/Guid.h>
    2122#include <VBox/com/ErrorInfo.h>
     
    110111
    111112/**
    112  * Callback handler for VirtualBox events
     113 *  Handler for global events.
    113114 */
    114 class VirtualBoxCallback :
    115   VBOX_SCRIPTABLE_IMPL(IVirtualBoxCallback)
     115class VirtualBoxEventListener :
     116  VBOX_SCRIPTABLE_IMPL(IEventListener)
    116117{
    117118public:
    118     VirtualBoxCallback()
     119    VirtualBoxEventListener()
    119120    {
    120121#ifndef VBOX_WITH_XPCOM
     
    124125    }
    125126
    126     virtual ~VirtualBoxCallback()
     127    virtual ~VirtualBoxEventListener()
    127128    {
    128129    }
     
    141142    }
    142143#endif
    143     VBOX_SCRIPTABLE_DISPATCH_IMPL(IVirtualBoxCallback)
     144    VBOX_SCRIPTABLE_DISPATCH_IMPL(IEventListener)
    144145
    145146    NS_DECL_ISUPPORTS
    146147
    147     STDMETHOD(OnMachineStateChange)(IN_BSTR machineId, MachineState_T state)
    148     {
    149         return VBOX_E_DONT_CALL_AGAIN;
    150     }
    151 
    152     STDMETHOD(OnMachineDataChange)(IN_BSTR machineId)
    153     {
    154         return VBOX_E_DONT_CALL_AGAIN;
    155     }
    156 
    157     STDMETHOD(OnExtraDataCanChange)(IN_BSTR machineId, IN_BSTR key, IN_BSTR value,
    158                                     BSTR *error, BOOL *changeAllowed)
    159     {
    160         /* we never disagree */
    161         if (!changeAllowed)
    162             return E_INVALIDARG;
    163         *changeAllowed = TRUE;
    164         return VBOX_E_DONT_CALL_AGAIN;
    165     }
    166 
    167     STDMETHOD(OnExtraDataChange)(IN_BSTR machineId, IN_BSTR key, IN_BSTR value)
    168     {
    169         return VBOX_E_DONT_CALL_AGAIN;
    170     }
    171 
    172     STDMETHOD(OnMediumRegistered)(IN_BSTR mediaId, DeviceType_T mediaType,
    173                                   BOOL registered)
    174     {
    175         return VBOX_E_DONT_CALL_AGAIN;
    176     }
    177 
    178     STDMETHOD(OnMachineRegistered)(IN_BSTR machineId, BOOL registered)
    179     {
    180         return VBOX_E_DONT_CALL_AGAIN;
    181     }
    182 
    183     STDMETHOD(OnSessionStateChange)(IN_BSTR machineId, SessionState_T state)
    184     {
    185         return VBOX_E_DONT_CALL_AGAIN;
    186     }
    187 
    188     STDMETHOD(OnSnapshotTaken)(IN_BSTR aMachineId, IN_BSTR aSnapshotId)
    189     {
    190         return VBOX_E_DONT_CALL_AGAIN;
    191     }
    192 
    193     STDMETHOD(OnSnapshotDeleted)(IN_BSTR aMachineId, IN_BSTR aSnapshotId)
    194     {
    195         return VBOX_E_DONT_CALL_AGAIN;
    196     }
    197 
    198     STDMETHOD(OnSnapshotChange)(IN_BSTR aMachineId, IN_BSTR aSnapshotId)
    199     {
    200         return VBOX_E_DONT_CALL_AGAIN;
    201     }
    202 
    203     STDMETHOD(OnGuestPropertyChange)(IN_BSTR machineId, IN_BSTR key, IN_BSTR value, IN_BSTR flags)
    204     {
    205 #ifdef VBOX_WITH_GUEST_PROPS
    206         Utf8Str utf8Key = key;
    207         if (utf8Key == "/VirtualBox/GuestInfo/OS/NoLoggedInUsers")
    208         {
    209             /* Check if this is our machine and the "disconnect on logout feature" is enabled. */
    210             BOOL fProcessDisconnectOnGuestLogout = FALSE;
    211             ComPtr <IMachine> machine;
    212             HRESULT hrc = S_OK;
    213 
    214             if (gConsole)
    215             {
    216                 hrc = gConsole->COMGETTER(Machine)(machine.asOutParam());
    217                 if (SUCCEEDED(hrc) && machine)
     148    STDMETHOD(HandleEvent)(IEvent * aEvent)
     149    {
     150        VBoxEventType_T aType = VBoxEventType_Invalid;
     151
     152        aEvent->COMGETTER(Type)(&aType);
     153        switch (aType)
     154        {
     155            case VBoxEventType_OnGuestPropertyChange:
     156            {
     157                ComPtr<IGuestPropertyChangeEvent> gpcev = aEvent;
     158                Assert(gpcev);
     159
     160                Bstr aKey;
     161                gpcev->COMGETTER(Name)(aKey.asOutParam());
     162
     163                if (aKey == Bstr("/VirtualBox/GuestInfo/OS/NoLoggedInUsers"))
    218164                {
    219                     Bstr id;
    220                     hrc = machine->COMGETTER(Id)(id.asOutParam());
    221                     if (id == machineId)
     165                    /* Check if this is our machine and the "disconnect on logout feature" is enabled. */
     166                    BOOL fProcessDisconnectOnGuestLogout = FALSE;
     167                    ComPtr <IMachine> machine;
     168                    HRESULT hrc = S_OK;
     169
     170                    if (gConsole)
    222171                    {
    223                         Bstr value1;
    224                         hrc = machine->GetExtraData(Bstr("VRDP/DisconnectOnGuestLogout"), value1.asOutParam());
    225                         if (SUCCEEDED(hrc) && value1 == "1")
     172                        hrc = gConsole->COMGETTER(Machine)(machine.asOutParam());
     173                        if (SUCCEEDED(hrc) && machine)
    226174                        {
    227                             fProcessDisconnectOnGuestLogout = TRUE;
    228                         }
    229                     }
    230                 }
    231             }
    232 
    233             if (fProcessDisconnectOnGuestLogout)
    234             {
    235                 Utf8Str utf8Value = value;
    236                 if (utf8Value == "true")
    237                 {
    238                     if (!mfNoLoggedInUsers) /* Only if the property really changes. */
    239                     {
    240                         mfNoLoggedInUsers = true;
    241 
    242                         /* If there is a VRDP connection, drop it. */
    243                         ComPtr<IRemoteDisplayInfo> info;
    244                         hrc = gConsole->COMGETTER(RemoteDisplayInfo)(info.asOutParam());
    245                         if (SUCCEEDED(hrc) && info)
    246                         {
    247                             ULONG cClients = 0;
    248                             hrc = info->COMGETTER(NumberOfClients)(&cClients);
    249                             if (SUCCEEDED(hrc) && cClients > 0)
     175                            Bstr id, machineId;
     176                            hrc = machine->COMGETTER(Id)(id.asOutParam());
     177                            gpcev->COMGETTER(MachineId)(machineId.asOutParam());
     178                            if (id == machineId)
    250179                            {
    251                                 ComPtr <IVRDPServer> vrdpServer;
    252                                 hrc = machine->COMGETTER(VRDPServer)(vrdpServer.asOutParam());
    253                                 if (SUCCEEDED(hrc) && vrdpServer)
     180                                Bstr value1;
     181                                hrc = machine->GetExtraData(Bstr("VRDP/DisconnectOnGuestLogout"), value1.asOutParam());
     182                                if (SUCCEEDED(hrc) && value1 == "1")
    254183                                {
    255                                     vrdpServer->COMSETTER(Enabled)(FALSE);
    256                                     vrdpServer->COMSETTER(Enabled)(TRUE);
     184                                    fProcessDisconnectOnGuestLogout = TRUE;
    257185                                }
    258186                            }
    259187                        }
    260188                    }
     189
     190                    if (fProcessDisconnectOnGuestLogout)
     191                    {
     192                        Bstr value;
     193                        gpcev->COMGETTER(Value)(value.asOutParam());
     194                        Utf8Str utf8Value = value;
     195                        if (utf8Value == "true")
     196                        {
     197                            if (!mfNoLoggedInUsers) /* Only if the property really changes. */
     198                            {
     199                                mfNoLoggedInUsers = true;
     200
     201                                /* If there is a VRDP connection, drop it. */
     202                                ComPtr<IRemoteDisplayInfo> info;
     203                                hrc = gConsole->COMGETTER(RemoteDisplayInfo)(info.asOutParam());
     204                                if (SUCCEEDED(hrc) && info)
     205                                {
     206                                    ULONG cClients = 0;
     207                                    hrc = info->COMGETTER(NumberOfClients)(&cClients);
     208                                    if (SUCCEEDED(hrc) && cClients > 0)
     209                                    {
     210                                        ComPtr <IVRDPServer> vrdpServer;
     211                                        hrc = machine->COMGETTER(VRDPServer)(vrdpServer.asOutParam());
     212                                        if (SUCCEEDED(hrc) && vrdpServer)
     213                                        {
     214                                            vrdpServer->COMSETTER(Enabled)(FALSE);
     215                                            vrdpServer->COMSETTER(Enabled)(TRUE);
     216                                        }
     217                                    }
     218                                }
     219                            }
     220                        }
     221                        else
     222                        {
     223                            mfNoLoggedInUsers = false;
     224                        }
     225                    }
    261226                }
    262                 else
    263                 {
    264                     mfNoLoggedInUsers = false;
    265                 }
    266             }
    267         }
     227                break;
     228            }
     229            default:
     230                AssertFailed();
     231        }
     232
    268233        return S_OK;
    269 #else  /* !VBOX_WITH_GUEST_PROPS */
    270         return VBOX_E_DONT_CALL_AGAIN;
    271 #endif /* !VBOX_WITH_GUEST_PROPS */
    272234    }
    273235
     
    280242};
    281243
     244
    282245/**
    283  *  Callback handler for machine events.
     246 *  Handler for machine events.
    284247 */
    285 class ConsoleCallback : VBOX_SCRIPTABLE_IMPL(IConsoleCallback)
     248class ConsoleEventListener :
     249  VBOX_SCRIPTABLE_IMPL(IEventListener)
    286250{
    287251public:
    288 
    289     ConsoleCallback()
     252    ConsoleEventListener()
    290253    {
    291254#ifndef VBOX_WITH_XPCOM
     
    295258    }
    296259
    297     virtual ~ConsoleCallback() {}
    298 
    299     NS_DECL_ISUPPORTS
     260    virtual ~ConsoleEventListener()
     261    {
     262    }
    300263
    301264#ifndef VBOX_WITH_XPCOM
     
    312275    }
    313276#endif
    314     VBOX_SCRIPTABLE_DISPATCH_IMPL(IConsoleCallback)
    315 
    316     STDMETHOD(OnMousePointerShapeChange)(BOOL visible, BOOL alpha, ULONG xHot, ULONG yHot,
    317                                          ULONG width, ULONG height, ComSafeArrayIn(BYTE,shape))
    318     {
    319         return VBOX_E_DONT_CALL_AGAIN;
    320     }
    321 
    322     STDMETHOD(OnMouseCapabilityChange)(BOOL supportsAbsolute, BOOL supportsRelative, BOOL needsHostCursor)
    323     {
    324         /* Emit absolute mouse event to actually enable the host mouse cursor. */
    325         if (supportsAbsolute && gConsole)
    326         {
    327             ComPtr<IMouse> mouse;
    328             gConsole->COMGETTER(Mouse)(mouse.asOutParam());
    329             if (mouse)
    330             {
    331                 mouse->PutMouseEventAbsolute(-1, -1, 0, 0 /* Horizontal wheel */, 0);
    332             }
    333         }
     277    VBOX_SCRIPTABLE_DISPATCH_IMPL(IEventListener)
     278
     279    NS_DECL_ISUPPORTS
     280
     281    STDMETHOD(HandleEvent)(IEvent * aEvent)
     282    {
     283        VBoxEventType_T aType = VBoxEventType_Invalid;
     284
     285        aEvent->COMGETTER(Type)(&aType);
     286        switch (aType)
     287        {
     288            case VBoxEventType_OnMouseCapabilityChange:
     289            {
     290
     291                ComPtr<IMouseCapabilityChangeEvent> mccev = aEvent;
     292                Assert(mccev);
     293
     294                BOOL fSupportsAbsolute = false;
     295                mccev->COMGETTER(SupportsAbsolute)(&fSupportsAbsolute);
     296
     297                /* Emit absolute mouse event to actually enable the host mouse cursor. */
     298                if (fSupportsAbsolute && gConsole)
     299                {
     300                    ComPtr<IMouse> mouse;
     301                    gConsole->COMGETTER(Mouse)(mouse.asOutParam());
     302                    if (mouse)
     303                    {
     304                        mouse->PutMouseEventAbsolute(-1, -1, 0, 0 /* Horizontal wheel */, 0);
     305                    }
     306                }
    334307#ifdef VBOX_WITH_VNC
    335         if (g_pFramebufferVNC)
    336             g_pFramebufferVNC->enableAbsMouse(supportsAbsolute);
    337 #endif
     308                if (g_pFramebufferVNC)
     309                    g_pFramebufferVNC->enableAbsMouse(fSupportsAbsolute);
     310#endif
     311                break;
     312            }
     313            case VBoxEventType_OnStateChange:
     314            {
     315                ComPtr<IStateChangeEvent> scev = aEvent;
     316                Assert(scev);
     317
     318                MachineState_T machineState;
     319                scev->COMGETTER(State)(&machineState);
     320
     321                gEventQ->postEvent(new StateChangeEvent(machineState));
     322                break;
     323            }
     324            case VBoxEventType_OnRemoteDisplayInfoChange:
     325            {
     326                ComPtr<IRemoteDisplayInfoChangeEvent> rdicev = aEvent;
     327                Assert(rdicev);
     328
     329#ifdef VBOX_WITH_VRDP
     330                if (gConsole)
     331                {
     332                    ComPtr<IRemoteDisplayInfo> info;
     333                    gConsole->COMGETTER(RemoteDisplayInfo)(info.asOutParam());
     334                    if (info)
     335                    {
     336                        LONG port;
     337                        info->COMGETTER(Port)(&port);
     338                        if (port != mLastVRDPPort)
     339                        {
     340                            if (port == -1)
     341                                RTPrintf("VRDP server is inactive.\n");
     342                            else if (port == 0)
     343                                RTPrintf("VRDP server failed to start.\n");
     344                            else
     345                                RTPrintf("Listening on port %d.\n", port);
     346
     347                            mLastVRDPPort = port;
     348                        }
     349                    }
     350                }
     351#endif
     352                break;
     353            }
     354            case VBoxEventType_OnCanShowWindow:
     355            {
     356                ComPtr<ICanShowWindowEvent> cswev = aEvent;
     357                Assert(cswev);
     358                cswev->AddVeto(NULL);
     359                break;
     360            }
     361            case VBoxEventType_OnShowWindow:
     362            {
     363                ComPtr<IShowWindowEvent> swev = aEvent;
     364                Assert(swev);
     365                swev->COMSETTER(WinId)(0);
     366                break;
     367            }
     368            default:
     369                AssertFailed();
     370        }
    338371        return S_OK;
    339     }
    340 
    341     STDMETHOD(OnKeyboardLedsChange)(BOOL fNumLock, BOOL fCapsLock, BOOL fScrollLock)
    342     {
    343         return VBOX_E_DONT_CALL_AGAIN;
    344     }
    345 
    346     STDMETHOD(OnStateChange)(MachineState_T machineState)
    347     {
    348         gEventQ->postEvent(new StateChangeEvent(machineState));
    349         return S_OK;
    350     }
    351 
    352     STDMETHOD(OnExtraDataChange)(BSTR key)
    353     {
    354         return VBOX_E_DONT_CALL_AGAIN;
    355     }
    356 
    357     STDMETHOD(OnAdditionsStateChange)()
    358     {
    359         return VBOX_E_DONT_CALL_AGAIN;
    360     }
    361 
    362     STDMETHOD(OnNetworkAdapterChange)(INetworkAdapter *aNetworkAdapter)
    363     {
    364         return VBOX_E_DONT_CALL_AGAIN;
    365     }
    366 
    367     STDMETHOD(OnSerialPortChange)(ISerialPort *aSerialPort)
    368     {
    369         return VBOX_E_DONT_CALL_AGAIN;
    370     }
    371 
    372     STDMETHOD(OnParallelPortChange)(IParallelPort *aParallelPort)
    373     {
    374         return VBOX_E_DONT_CALL_AGAIN;
    375     }
    376 
    377     STDMETHOD(OnVRDPServerChange)()
    378     {
    379         return VBOX_E_DONT_CALL_AGAIN;
    380     }
    381 
    382     STDMETHOD(OnRemoteDisplayInfoChange)()
    383     {
    384 #ifdef VBOX_WITH_VRDP
    385         if (gConsole)
    386         {
    387             ComPtr<IRemoteDisplayInfo> info;
    388             gConsole->COMGETTER(RemoteDisplayInfo)(info.asOutParam());
    389             if (info)
    390             {
    391                 LONG port;
    392                 info->COMGETTER(Port)(&port);
    393                 if (port != mLastVRDPPort)
    394                 {
    395                     if (port == -1)
    396                         RTPrintf("VRDP server is inactive.\n");
    397                     else if (port == 0)
    398                         RTPrintf("VRDP server failed to start.\n");
    399                     else
    400                         RTPrintf("Listening on port %d.\n", port);
    401 
    402                     mLastVRDPPort = port;
    403                 }
    404             }
    405         }
    406 #endif
    407         return S_OK;
    408     }
    409 
    410     STDMETHOD(OnUSBControllerChange)()
    411     {
    412         return VBOX_E_DONT_CALL_AGAIN;
    413     }
    414 
    415     STDMETHOD(OnStorageControllerChange)()
    416     {
    417         return VBOX_E_DONT_CALL_AGAIN;
    418     }
    419 
    420     STDMETHOD(OnMediumChange)(IMediumAttachment * /* aMediumAttachment */)
    421     {
    422         return VBOX_E_DONT_CALL_AGAIN;
    423     }
    424 
    425     STDMETHOD(OnCPUChange)(ULONG /*aCPU*/, BOOL /* aRemove */)
    426     {
    427         return VBOX_E_DONT_CALL_AGAIN;
    428     }
    429 
    430     STDMETHOD(OnUSBDeviceStateChange)(IUSBDevice *aDevice, BOOL aAttached,
    431                                       IVirtualBoxErrorInfo *aError)
    432     {
    433         return VBOX_E_DONT_CALL_AGAIN;
    434     }
    435 
    436     STDMETHOD(OnSharedFolderChange)(Scope_T aScope)
    437     {
    438         return VBOX_E_DONT_CALL_AGAIN;
    439     }
    440 
    441     STDMETHOD(OnRuntimeError)(BOOL fatal, IN_BSTR id, IN_BSTR message)
    442     {
    443         return VBOX_E_DONT_CALL_AGAIN;
    444     }
    445 
    446     STDMETHOD(OnCanShowWindow)(BOOL *canShow)
    447     {
    448         if (!canShow)
    449             return E_POINTER;
    450         /* Headless windows should not be shown */
    451         *canShow = FALSE;
    452         return S_OK;
    453     }
    454 
    455     STDMETHOD(OnShowWindow)(ULONG64 *winId)
    456     {
    457         /* OnCanShowWindow() always returns FALSE, so this call should never
    458          * happen. */
    459         AssertFailed();
    460         if (!winId)
    461             return E_POINTER;
    462         *winId = 0;
    463         return E_NOTIMPL;
    464372    }
    465373
     
    473381
    474382#ifdef VBOX_WITH_XPCOM
    475 NS_DECL_CLASSINFO(VirtualBoxCallback)
    476 NS_IMPL_THREADSAFE_ISUPPORTS1_CI(VirtualBoxCallback, IVirtualBoxCallback)
    477 NS_DECL_CLASSINFO(ConsoleCallback)
    478 NS_IMPL_THREADSAFE_ISUPPORTS1_CI(ConsoleCallback, IConsoleCallback)
     383NS_DECL_CLASSINFO(VirtualBoxEventListener)
     384NS_IMPL_THREADSAFE_ISUPPORTS1_CI(VirtualBoxEventListener, IEventListener)
     385NS_DECL_CLASSINFO(ConsoleEventListener)
     386NS_IMPL_THREADSAFE_ISUPPORTS1_CI(ConsoleEventListener, IEventListener)
    479387#endif
    480388
     
    868776    ComPtr<ISession> session;
    869777    bool fSessionOpened = false;
    870     VirtualBoxCallback *vboxCallback = NULL;
     778    IEventListener *vboxListener = NULL, *consoleListener = NULL;
    871779
    872780    do
     
    1081989        gEventQ = com::EventQueue::getMainEventQueue();
    1082990
    1083         /* register a callback for machine events */
    1084         {
    1085             ConsoleCallback *callback = new ConsoleCallback();
    1086             callback->AddRef();
    1087             CHECK_ERROR(console, RegisterCallback(callback));
    1088             callback->Release();
    1089             if (FAILED(rc))
    1090                 break;
     991        /* Console events registration. */
     992        {
     993            ComPtr<IEventSource> es;
     994            CHECK_ERROR(console, COMGETTER(EventSource)(es.asOutParam()));
     995            consoleListener = new ConsoleEventListener();
     996            consoleListener->AddRef();
     997            com::SafeArray <VBoxEventType_T> eventTypes(5);
     998            eventTypes.push_back(VBoxEventType_OnMouseCapabilityChange);
     999            eventTypes.push_back(VBoxEventType_OnStateChange);
     1000            eventTypes.push_back(VBoxEventType_OnRemoteDisplayInfoChange);
     1001            eventTypes.push_back(VBoxEventType_OnCanShowWindow);
     1002            eventTypes.push_back(VBoxEventType_OnShowWindow);
     1003            CHECK_ERROR(es, RegisterListener(consoleListener, ComSafeArrayAsInParam(eventTypes), true));
    10911004        }
    10921005
     
    11711084        }
    11721085
    1173         /* VirtualBox callback registration. */
    1174         vboxCallback = new VirtualBoxCallback();
    1175         vboxCallback->AddRef();
    1176         CHECK_ERROR(virtualBox, RegisterCallback(vboxCallback));
    1177         vboxCallback->Release();
    1178         if (FAILED(rc))
    1179             break;
     1086        /* VirtualBox events registration. */
     1087        {
     1088            ComPtr<IEventSource> es;
     1089            CHECK_ERROR(virtualBox, COMGETTER(EventSource)(es.asOutParam()));
     1090            vboxListener = new VirtualBoxEventListener();
     1091            vboxListener->AddRef();
     1092            com::SafeArray <VBoxEventType_T> eventTypes(1);
     1093            eventTypes.push_back(VBoxEventType_OnGuestPropertyChange);
     1094            CHECK_ERROR(es, RegisterListener(vboxListener, ComSafeArrayAsInParam(eventTypes), true));
     1095        }
    11801096
    11811097#ifdef VBOX_WITH_SAVESTATE_ON_SIGNAL
     
    12071123
    12081124    /* VirtualBox callback unregistration. */
    1209     if (vboxCallback)
    1210     {
    1211         vboxCallback->AddRef();
    1212         CHECK_ERROR(virtualBox, UnregisterCallback(vboxCallback));
    1213         vboxCallback->Release();
     1125    if (vboxListener)
     1126    {
     1127        ComPtr<IEventSource> es;
     1128        CHECK_ERROR(virtualBox, COMGETTER(EventSource)(es.asOutParam()));
     1129        CHECK_ERROR(es, UnregisterListener(vboxListener));
     1130        vboxListener->Release();
     1131    }
     1132
     1133    /* Console callback unregistration. */
     1134    if (consoleListener)
     1135    {
     1136        ComPtr<IEventSource> es;
     1137        CHECK_ERROR(gConsole, COMGETTER(EventSource)(es.asOutParam()));
     1138        CHECK_ERROR(es, UnregisterListener(consoleListener));
     1139        consoleListener->Release();
    12141140    }
    12151141
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette