Changeset 30606 in vbox for trunk/src/VBox/Frontends/VBoxHeadless
- Timestamp:
- Jul 5, 2010 12:26:27 PM (14 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Frontends/VBoxHeadless/VBoxHeadless.cpp
r30580 r30606 18 18 #include <VBox/com/com.h> 19 19 #include <VBox/com/string.h> 20 #include <VBox/com/array.h> 20 21 #include <VBox/com/Guid.h> 21 22 #include <VBox/com/ErrorInfo.h> … … 110 111 111 112 /** 112 * Callback handler for VirtualBox events113 * Handler for global events. 113 114 */ 114 class VirtualBox Callback:115 VBOX_SCRIPTABLE_IMPL(I VirtualBoxCallback)115 class VirtualBoxEventListener : 116 VBOX_SCRIPTABLE_IMPL(IEventListener) 116 117 { 117 118 public: 118 VirtualBox Callback()119 VirtualBoxEventListener() 119 120 { 120 121 #ifndef VBOX_WITH_XPCOM … … 124 125 } 125 126 126 virtual ~VirtualBox Callback()127 virtual ~VirtualBoxEventListener() 127 128 { 128 129 } … … 141 142 } 142 143 #endif 143 VBOX_SCRIPTABLE_DISPATCH_IMPL(I VirtualBoxCallback)144 VBOX_SCRIPTABLE_DISPATCH_IMPL(IEventListener) 144 145 145 146 NS_DECL_ISUPPORTS 146 147 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")) 218 164 { 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) 222 171 { 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) 226 174 { 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) 250 179 { 251 ComPtr <IVRDPServer> vrdpServer;252 hrc = machine-> COMGETTER(VRDPServer)(vrdpServer.asOutParam());253 if (SUCCEEDED(hrc) && v rdpServer)180 Bstr value1; 181 hrc = machine->GetExtraData(Bstr("VRDP/DisconnectOnGuestLogout"), value1.asOutParam()); 182 if (SUCCEEDED(hrc) && value1 == "1") 254 183 { 255 vrdpServer->COMSETTER(Enabled)(FALSE); 256 vrdpServer->COMSETTER(Enabled)(TRUE); 184 fProcessDisconnectOnGuestLogout = TRUE; 257 185 } 258 186 } 259 187 } 260 188 } 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 } 261 226 } 262 else263 {264 mfNoLoggedInUsers = false;265 }266 267 } 227 break; 228 } 229 default: 230 AssertFailed(); 231 } 232 268 233 return S_OK; 269 #else /* !VBOX_WITH_GUEST_PROPS */270 return VBOX_E_DONT_CALL_AGAIN;271 #endif /* !VBOX_WITH_GUEST_PROPS */272 234 } 273 235 … … 280 242 }; 281 243 244 282 245 /** 283 * Callback handler for machine events.246 * Handler for machine events. 284 247 */ 285 class ConsoleCallback : VBOX_SCRIPTABLE_IMPL(IConsoleCallback) 248 class ConsoleEventListener : 249 VBOX_SCRIPTABLE_IMPL(IEventListener) 286 250 { 287 251 public: 288 289 ConsoleCallback() 252 ConsoleEventListener() 290 253 { 291 254 #ifndef VBOX_WITH_XPCOM … … 295 258 } 296 259 297 virtual ~Console Callback() {}298 299 NS_DECL_ISUPPORTS260 virtual ~ConsoleEventListener() 261 { 262 } 300 263 301 264 #ifndef VBOX_WITH_XPCOM … … 312 275 } 313 276 #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 } 334 307 #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 } 338 371 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_VRDP385 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 else400 RTPrintf("Listening on port %d.\n", port);401 402 mLastVRDPPort = port;403 }404 }405 }406 #endif407 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 never458 * happen. */459 AssertFailed();460 if (!winId)461 return E_POINTER;462 *winId = 0;463 return E_NOTIMPL;464 372 } 465 373 … … 473 381 474 382 #ifdef VBOX_WITH_XPCOM 475 NS_DECL_CLASSINFO(VirtualBox Callback)476 NS_IMPL_THREADSAFE_ISUPPORTS1_CI(VirtualBox Callback, IVirtualBoxCallback)477 NS_DECL_CLASSINFO(Console Callback)478 NS_IMPL_THREADSAFE_ISUPPORTS1_CI(Console Callback, IConsoleCallback)383 NS_DECL_CLASSINFO(VirtualBoxEventListener) 384 NS_IMPL_THREADSAFE_ISUPPORTS1_CI(VirtualBoxEventListener, IEventListener) 385 NS_DECL_CLASSINFO(ConsoleEventListener) 386 NS_IMPL_THREADSAFE_ISUPPORTS1_CI(ConsoleEventListener, IEventListener) 479 387 #endif 480 388 … … 868 776 ComPtr<ISession> session; 869 777 bool fSessionOpened = false; 870 VirtualBoxCallback *vboxCallback= NULL;778 IEventListener *vboxListener = NULL, *consoleListener = NULL; 871 779 872 780 do … … 1081 989 gEventQ = com::EventQueue::getMainEventQueue(); 1082 990 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)); 1091 1004 } 1092 1005 … … 1171 1084 } 1172 1085 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 } 1180 1096 1181 1097 #ifdef VBOX_WITH_SAVESTATE_ON_SIGNAL … … 1207 1123 1208 1124 /* 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(); 1214 1140 } 1215 1141
Note:
See TracChangeset
for help on using the changeset viewer.