Changeset 28959 in vbox
- Timestamp:
- May 2, 2010 7:36:11 PM (15 years ago)
- Location:
- trunk/src/VBox/Main
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/ConsoleImpl.cpp
r28955 r28959 242 242 }; 243 243 244 // ConsoleCallbackRegistration 245 //////////////////////////////////////////////////////////////////////////////// 246 247 /** 248 * Registered IConsoleCallback, used by Console::CallbackList and 249 * Console::mCallbacks. 250 * 251 * In addition to keeping the interface pointer this also keeps track of the 252 * methods that asked to not be called again. The latter is for reducing 253 * unnecessary IPC. 254 */ 255 class ConsoleCallbackRegistration 256 { 257 public: 258 ComPtr<IConsoleCallback> ptrICb; 259 /** Bitmap of disabled callback methods, that is methods that has return 260 * VBOX_E_DONT_CALL_AGAIN. */ 261 uint32_t bmDisabled; 262 /** Callback bit indexes (for bmDisabled). */ 263 typedef enum 264 { 265 kOnMousePointerShapeChange = 0, 266 kOnMouseCapabilityChange, 267 kOnKeyboardLedsChange, 268 kOnStateChange, 269 kOnAdditionsStateChange, 270 kOnNetworkAdapterChange, 271 kOnSerialPortChange, 272 kOnParallelPortChange, 273 kOnStorageControllerChange, 274 kOnMediumChange, 275 kOnCPUChange, 276 kOnVRDPServerChange, 277 kOnRemoteDisplayInfoChange, 278 kOnUSBControllerChange, 279 kOnUSBDeviceStateChange, 280 kOnSharedFolderChange, 281 kOnRuntimeError, 282 kOnCanShowWindow, 283 kOnShowWindow 284 } CallbackBit; 285 286 ConsoleCallbackRegistration(IConsoleCallback *pIConsoleCallback) 287 : ptrICb(pIConsoleCallback), bmDisabled(0) 288 { 289 /* nothing */ 290 } 291 292 ~ConsoleCallbackRegistration() 293 { 294 /* nothing */ 295 } 296 297 /** Equal operator for std::find. */ 298 bool operator==(const ConsoleCallbackRegistration &rThat) const 299 { 300 return this->ptrICb == rThat.ptrICb; 301 } 302 303 /** 304 * Checks if the callback is wanted, i.e. if the method hasn't yet returned 305 * VBOX_E_DONT_CALL_AGAIN. 306 * @returns @c true if it is wanted, @c false if not. 307 * @param enmBit The callback, be sure to get this one right! 308 */ 309 inline bool isWanted(CallbackBit enmBit) const 310 { 311 return !ASMBitTest(&bmDisabled, enmBit); 312 } 313 314 /** 315 * Called in response to VBOX_E_DONT_CALL_AGAIN. 316 * @param enmBit The callback, be sure to get this one right! 317 */ 318 inline void setDontCallAgain(CallbackBit enmBit) 319 { 320 ASMAtomicBitSet(&bmDisabled, enmBit); 321 } 322 323 /** 324 * Handle a callback return code, picking up VBOX_E_DONT_CALL_AGAIN. 325 * 326 * @returns hrc or S_OK if VBOX_E_DONT_CALL_AGAIN. 327 * @param enmBit The callback, be sure to get this one right! 328 * @param hrc The status code returned by the callback. 329 */ 330 inline HRESULT handleResult(CallbackBit enmBit, HRESULT hrc) 331 { 332 if (hrc == VBOX_E_DONT_CALL_AGAIN) 333 { 334 setDontCallAgain(enmBit); 335 hrc = S_OK; 336 } 337 return hrc; 338 } 339 }; 340 341 /** 342 * Macro for iterating the callback list (Console::mCallbacks) and invoking the 343 * given method on each entry. 344 * 345 * This handles VBOX_E_DONT_CALL_AGAIN as well as removing dead interfaces 346 * which. This makes the code a big and clunky, thus this macro. It may make 347 * debugging and selective logging a bit of a pain, but duplicating this code 348 * some seventeen times is much more of a pain. 349 * 350 * The caller must hold the console object lock - read or write, we don't care. 351 * The caller must be a Console method - the console members accessible thru the 352 * 'this' pointer. 353 * 354 * @param CallbackMethod The callback method, like OnKeyboardLedsChange. 355 * @param Args The method arguments enclosed in parentheses. 356 */ 357 #define CONSOLE_DO_CALLBACKS(CallbackMethod, Args) \ 358 do \ 359 { \ 360 CallbackList::iterator it = this->mCallbacks.begin(); \ 361 while (it != this->mCallbacks.end()) \ 362 { \ 363 if (it->isWanted(ConsoleCallbackRegistration::k ## CallbackMethod)) \ 364 { \ 365 HRESULT hrc = it->ptrICb-> CallbackMethod Args; \ 366 hrc = it->handleResult(ConsoleCallbackRegistration::k ## CallbackMethod, hrc); \ 367 if (FAILED_DEAD_INTERFACE(hrc)) \ 368 { \ 369 it = this->mCallbacks.erase(it); \ 370 continue; \ 371 } \ 372 } \ 373 ++it; \ 374 } \ 375 } while (0) 376 377 244 378 // constructor / destructor 245 379 ///////////////////////////////////////////////////////////////////////////// … … 2622 2756 2623 2757 /* notify console callbacks after the folder is added to the list */ 2624 { 2625 CallbackList::iterator it = mCallbacks.begin(); 2626 while (it != mCallbacks.end()) 2627 (*it++)->OnSharedFolderChange(Scope_Session); 2628 } 2758 CONSOLE_DO_CALLBACKS(OnSharedFolderChange,(Scope_Session)); 2629 2759 2630 2760 return rc; … … 2683 2813 2684 2814 /* notify console callbacks after the folder is removed to the list */ 2685 { 2686 CallbackList::iterator it = mCallbacks.begin(); 2687 while (it != mCallbacks.end()) 2688 (*it++)->OnSharedFolderChange(Scope_Session); 2689 } 2815 CONSOLE_DO_CALLBACKS(OnSharedFolderChange,(Scope_Session)); 2690 2816 2691 2817 return rc; … … 3380 3506 /* notify console callbacks on success */ 3381 3507 if (SUCCEEDED(rc)) 3382 { 3383 CallbackList::iterator it = mCallbacks.begin(); 3384 while (it != mCallbacks.end()) 3385 (*it++)->OnNetworkAdapterChange(aNetworkAdapter); 3386 } 3508 CONSOLE_DO_CALLBACKS(OnNetworkAdapterChange,(aNetworkAdapter)); 3387 3509 3388 3510 LogFlowThisFunc(("Leaving rc=%#x\n", rc)); … … 3600 3722 /* notify console callbacks on success */ 3601 3723 if (SUCCEEDED(rc)) 3602 { 3603 CallbackList::iterator it = mCallbacks.begin(); 3604 while (it != mCallbacks.end()) 3605 (*it++)->OnSerialPortChange(aSerialPort); 3606 } 3724 CONSOLE_DO_CALLBACKS(OnSerialPortChange,(aSerialPort)); 3607 3725 3608 3726 LogFlowThisFunc(("Leaving rc=%#x\n", rc)); … … 3638 3756 /* notify console callbacks on success */ 3639 3757 if (SUCCEEDED(rc)) 3640 { 3641 CallbackList::iterator it = mCallbacks.begin(); 3642 while (it != mCallbacks.end()) 3643 (*it++)->OnParallelPortChange(aParallelPort); 3644 } 3758 CONSOLE_DO_CALLBACKS(OnParallelPortChange,(aParallelPort)); 3645 3759 3646 3760 LogFlowThisFunc(("Leaving rc=%#x\n", rc)); … … 3676 3790 /* notify console callbacks on success */ 3677 3791 if (SUCCEEDED(rc)) 3678 { 3679 CallbackList::iterator it = mCallbacks.begin(); 3680 while (it != mCallbacks.end()) 3681 (*it++)->OnStorageControllerChange(); 3682 } 3792 CONSOLE_DO_CALLBACKS(OnStorageControllerChange,()); 3683 3793 3684 3794 LogFlowThisFunc(("Leaving rc=%#x\n", rc)); … … 3714 3824 /* notify console callbacks on success */ 3715 3825 if (SUCCEEDED(rc)) 3716 { 3717 CallbackList::iterator it = mCallbacks.begin(); 3718 while (it != mCallbacks.end()) 3719 (*it++)->OnMediumChange(aMediumAttachment); 3720 } 3826 CONSOLE_DO_CALLBACKS(OnMediumChange,(aMediumAttachment)); 3721 3827 3722 3828 LogFlowThisFunc(("Leaving rc=%#x\n", rc)); … … 3755 3861 /* notify console callbacks on success */ 3756 3862 if (SUCCEEDED(rc)) 3757 { 3758 CallbackList::iterator it = mCallbacks.begin(); 3759 while (it != mCallbacks.end()) 3760 (*it++)->OnCPUChange(aCPU, aRemove); 3761 } 3863 CONSOLE_DO_CALLBACKS(OnCPUChange,(aCPU, aRemove)); 3762 3864 3763 3865 LogFlowThisFunc(("Leaving rc=%#x\n", rc)); … … 3820 3922 /* notify console callbacks on success */ 3821 3923 if (SUCCEEDED(rc)) 3822 { 3823 CallbackList::iterator it = mCallbacks.begin(); 3824 while (it != mCallbacks.end()) 3825 (*it++)->OnVRDPServerChange(); 3826 } 3924 CONSOLE_DO_CALLBACKS(OnVRDPServerChange,()); 3827 3925 3828 3926 return rc; … … 3839 3937 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS); 3840 3938 3841 CallbackList::iterator it = mCallbacks.begin(); 3842 while (it != mCallbacks.end()) 3843 (*it++)->OnRemoteDisplayInfoChange(); 3939 CONSOLE_DO_CALLBACKS(OnRemoteDisplayInfoChange,()); 3844 3940 } 3845 3941 … … 3879 3975 /* notify console callbacks on success */ 3880 3976 if (SUCCEEDED(rc)) 3881 { 3882 CallbackList::iterator it = mCallbacks.begin(); 3883 while (it != mCallbacks.end()) 3884 (*it++)->OnUSBControllerChange(); 3885 } 3977 CONSOLE_DO_CALLBACKS(OnUSBControllerChange,()); 3886 3978 3887 3979 return rc; … … 3907 3999 if (SUCCEEDED(rc)) 3908 4000 { 3909 CallbackList::iterator it = mCallbacks.begin();3910 while (it != mCallbacks.end())3911 (*it++)->OnSharedFolderChange(aGlobal ? (Scope_T)Scope_Global3912 : (Scope_T)Scope_Machine);4001 if (aGlobal) 4002 CONSOLE_DO_CALLBACKS(OnSharedFolderChange,(Scope_Global)); 4003 else 4004 CONSOLE_DO_CALLBACKS(OnSharedFolderChange,(Scope_Machine)); 3913 4005 } 3914 4006 … … 4586 4678 mCallbackData.mpsc.valid = true; 4587 4679 4588 CallbackList::iterator it = mCallbacks.begin(); 4589 while (it != mCallbacks.end()) 4590 (*it++)->OnMousePointerShapeChange(fVisible, fAlpha, xHot, yHot, 4591 width, height, (BYTE *) pShape); 4680 CONSOLE_DO_CALLBACKS(OnMousePointerShapeChange,(fVisible, fAlpha, xHot, yHot, width, height, (BYTE *) pShape)); 4592 4681 4593 4682 #if 0 … … 4616 4705 mCallbackData.mcc.valid = true; 4617 4706 4618 CallbackList::iterator it = mCallbacks.begin(); 4619 while (it != mCallbacks.end()) 4620 { 4621 Log2(("Console::onMouseCapabilityChange: calling %p\n", (void*)*it)); 4622 (*it++)->OnMouseCapabilityChange(supportsAbsolute, supportsRelative, needsHostCursor); 4623 } 4707 CONSOLE_DO_CALLBACKS(OnMouseCapabilityChange,(supportsAbsolute, supportsRelative, needsHostCursor)); 4624 4708 } 4625 4709 … … 4633 4717 4634 4718 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS); 4635 4636 CallbackList::iterator it = mCallbacks.begin(); 4637 while (it != mCallbacks.end()) 4638 (*it++)->OnStateChange(machineState); 4719 CONSOLE_DO_CALLBACKS(OnStateChange,(machineState)); 4639 4720 } 4640 4721 … … 4648 4729 4649 4730 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS); 4650 4651 CallbackList::iterator it = mCallbacks.begin(); 4652 while (it != mCallbacks.end()) 4653 (*it++)->OnAdditionsStateChange(); 4731 CONSOLE_DO_CALLBACKS(OnAdditionsStateChange,()); 4654 4732 } 4655 4733 … … 4688 4766 mCallbackData.klc.valid = true; 4689 4767 4690 CallbackList::iterator it = mCallbacks.begin(); 4691 while (it != mCallbacks.end()) 4692 (*it++)->OnKeyboardLedsChange(fNumLock, fCapsLock, fScrollLock); 4768 CONSOLE_DO_CALLBACKS(OnKeyboardLedsChange,(fNumLock, fCapsLock, fScrollLock)); 4693 4769 } 4694 4770 … … 4703 4779 4704 4780 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS); 4705 4706 CallbackList::iterator it = mCallbacks.begin(); 4707 while (it != mCallbacks.end()) 4708 (*it++)->OnUSBDeviceStateChange(aDevice, aAttached, aError); 4781 CONSOLE_DO_CALLBACKS(OnUSBDeviceStateChange,(aDevice, aAttached, aError)); 4709 4782 } 4710 4783 … … 4718 4791 4719 4792 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS); 4720 4721 CallbackList::iterator it = mCallbacks.begin(); 4722 while (it != mCallbacks.end()) 4723 (*it++)->OnRuntimeError(aFatal, aErrorID, aMessage); 4793 CONSOLE_DO_CALLBACKS(OnRuntimeError,(aFatal, aErrorID, aMessage)); 4724 4794 } 4725 4795 … … 4739 4809 4740 4810 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS); 4741 4742 HRESULT rc = S_OK;4743 4811 CallbackList::iterator it = mCallbacks.begin(); 4744 4745 4812 if (aCheck) 4746 4813 { 4747 4814 while (it != mCallbacks.end()) 4748 4815 { 4749 BOOL canShow = FALSE; 4750 rc = (*it++)->OnCanShowWindow(&canShow); 4751 AssertComRC(rc); 4752 if (FAILED(rc) || !canShow) 4753 return rc; 4816 if (it->isWanted(ConsoleCallbackRegistration::kOnCanShowWindow)) 4817 { 4818 BOOL canShow = FALSE; 4819 HRESULT hrc = it->ptrICb->OnCanShowWindow(&canShow); 4820 hrc = it->handleResult(ConsoleCallbackRegistration::kOnCanShowWindow, hrc); 4821 if (FAILED_DEAD_INTERFACE(hrc)) 4822 { 4823 it = this->mCallbacks.erase(it); 4824 continue; 4825 } 4826 AssertComRC(hrc); 4827 if (FAILED(hrc) || !canShow) 4828 return hrc; 4829 } 4830 ++it; 4754 4831 } 4755 4832 *aCanShow = TRUE; … … 4759 4836 while (it != mCallbacks.end()) 4760 4837 { 4761 ULONG64 winId = 0; 4762 rc = (*it++)->OnShowWindow(&winId); 4763 AssertComRC(rc); 4764 if (FAILED(rc)) 4765 return rc; 4766 /* only one callback may return non-null winId */ 4767 Assert(*aWinId == 0 || winId == 0); 4768 if (*aWinId == 0) 4769 *aWinId = winId; 4838 if (it->isWanted(ConsoleCallbackRegistration::kOnShowWindow)) 4839 { 4840 ULONG64 winId = 0; 4841 HRESULT hrc = it->ptrICb->OnShowWindow(&winId); 4842 hrc = it->handleResult(ConsoleCallbackRegistration::kOnCanShowWindow, hrc); 4843 if (FAILED_DEAD_INTERFACE(hrc)) 4844 { 4845 it = this->mCallbacks.erase(it); 4846 continue; 4847 } 4848 AssertComRC(hrc); 4849 if (FAILED(hrc)) 4850 return hrc; 4851 4852 /* only one callback may return non-null winId */ 4853 Assert(*aWinId == 0 || winId == 0); 4854 if (*aWinId == 0) 4855 *aWinId = winId; 4856 } 4770 4857 } 4771 4858 } -
trunk/src/VBox/Main/idl/VirtualBox.xidl
r28930 r28959 6161 6161 Notification when the guest mouse pointer shape has 6162 6162 changed. The new shape data is given. 6163 <result name="VBOX_E_DONT_CALL_AGAIN"> 6164 Do not call again, this method is a NOP. 6165 </result> 6163 6166 </desc> 6164 6167 <param name="visible" type="boolean" dir="in"> … … 6229 6232 Notification when the mouse capabilities reported by the 6230 6233 guest have changed. The new capabilities are passed. 6234 <result name="VBOX_E_DONT_CALL_AGAIN"> 6235 Do not call again, this method is a NOP. 6236 </result> 6231 6237 </desc> 6232 6238 <param name="supportsAbsolute" type="boolean" dir="in"/> … … 6239 6245 Notification when the guest OS executes the KBD_CMD_SET_LEDS command 6240 6246 to alter the state of the keyboard LEDs. 6247 <result name="VBOX_E_DONT_CALL_AGAIN"> 6248 Do not call again, this method is a NOP. 6249 </result> 6241 6250 </desc> 6242 6251 <param name="numLock" type="boolean" dir="in"/> … … 6249 6258 Notification when the execution state of the machine has changed. 6250 6259 The new state will be given. 6260 <result name="VBOX_E_DONT_CALL_AGAIN"> 6261 Do not call again, this method is a NOP. 6262 </result> 6251 6263 </desc> 6252 6264 <param name="state" type="MachineState" dir="in"/> … … 6267 6279 changes. Interested callees should use INetworkAdapter methods and 6268 6280 attributes to find out what has changed. 6281 <result name="VBOX_E_DONT_CALL_AGAIN"> 6282 Do not call again, this method is a NOP. 6283 </result> 6269 6284 </desc> 6270 6285 <param name="networkAdapter" type="INetworkAdapter" dir="in"> … … 6279 6294 Interested callees should use ISerialPort methods and attributes 6280 6295 to find out what has changed. 6296 <result name="VBOX_E_DONT_CALL_AGAIN"> 6297 Do not call again, this method is a NOP. 6298 </result> 6281 6299 </desc> 6282 6300 <param name="serialPort" type="ISerialPort" dir="in"> … … 6291 6309 changes. Interested callees should use ISerialPort methods and 6292 6310 attributes to find out what has changed. 6311 <result name="VBOX_E_DONT_CALL_AGAIN"> 6312 Do not call again, this method is a NOP. 6313 </result> 6293 6314 </desc> 6294 6315 <param name="parallelPort" type="IParallelPort" dir="in"> … … 6303 6324 changes. Interested callees should query the corresponding collections 6304 6325 to find out what has changed. 6326 <result name="VBOX_E_DONT_CALL_AGAIN"> 6327 Do not call again, this method is a NOP. 6328 </result> 6305 6329 </desc> 6306 6330 </method> … … 6311 6335 <link to="IMachine::mediumAttachments">medium attachment</link> 6312 6336 changes. 6337 <result name="VBOX_E_DONT_CALL_AGAIN"> 6338 Do not call again, this method is a NOP. 6339 </result> 6313 6340 </desc> 6314 6341 <param name="mediumAttachment" type="IMediumAttachment" dir="in"> … … 6320 6347 <desc> 6321 6348 Notification when a CPU changes. 6349 <result name="VBOX_E_DONT_CALL_AGAIN"> 6350 Do not call again, this method is a NOP. 6351 </result> 6322 6352 </desc> 6323 6353 <param name="cpu" type="unsigned long" dir="in"> … … 6335 6365 Interested callees should use IVRDPServer methods and attributes to 6336 6366 find out what has changed. 6367 <result name="VBOX_E_DONT_CALL_AGAIN"> 6368 Do not call again, this method is a NOP. 6369 </result> 6337 6370 </desc> 6338 6371 </method> … … 6343 6376 should use <link to="IConsole::RemoteDisplayInfo">IRemoteDisplayInfo</link> 6344 6377 attributes to find out what is the current status. 6378 <result name="VBOX_E_DONT_CALL_AGAIN"> 6379 Do not call again, this method is a NOP. 6380 </result> 6345 6381 </desc> 6346 6382 </method> … … 6352 6388 Interested callees should use IUSBController methods and attributes to 6353 6389 find out what has changed. 6390 <result name="VBOX_E_DONT_CALL_AGAIN"> 6391 Do not call again, this method is a NOP. 6392 </result> 6354 6393 </desc> 6355 6394 </method> … … 6375 6414 message describing the failure. 6376 6415 6416 <result name="VBOX_E_DONT_CALL_AGAIN"> 6417 Do not call again, this method is a NOP. 6418 </result> 6377 6419 </desc> 6378 6420 <param name="device" type="IUSBDevice" dir="in"> … … 6403 6445 should use query the corresponding collections to find out what has 6404 6446 changed. 6447 <result name="VBOX_E_DONT_CALL_AGAIN"> 6448 Do not call again, this method is a NOP. 6449 </result> 6405 6450 </desc> 6406 6451 <param name="scope" type="Scope" dir="in"> … … 6469 6514 </note> 6470 6515 6516 <result name="VBOX_E_DONT_CALL_AGAIN"> 6517 Do not call again, this method is a NOP. 6518 </result> 6471 6519 </desc> 6472 6520 <param name="fatal" type="boolean" dir="in"> … … 6501 6549 actually manages console window activation. 6502 6550 </note> 6551 6552 <result name="VBOX_E_DONT_CALL_AGAIN"> 6553 Do not call again, this method is a NOP. 6554 </result> 6503 6555 </desc> 6504 6556 <param name="canShow" type="boolean" dir="return"> … … 6545 6597 manages console window activation. 6546 6598 </note> 6599 6600 <result name="VBOX_E_DONT_CALL_AGAIN"> 6601 Do not call again, this method is a NOP. 6602 </result> 6547 6603 </desc> 6548 6604 <param name="winId" type="unsigned long long" dir="return"> -
trunk/src/VBox/Main/include/ConsoleImpl.h
r28835 r28959 34 34 class AudioSniffer; 35 35 class ConsoleVRDPServer; 36 class ConsoleCallbackRegistration; /* See ConsoleImpl.cpp. */ 36 37 class VMMDev; 37 38 class Progress; … … 650 651 ComObjPtr<Progress> mptrCancelableProgress; 651 652 652 typedef std::list <ComPtr<IConsoleCallback>> CallbackList;653 typedef std::list<ConsoleCallbackRegistration> CallbackList; 653 654 CallbackList mCallbacks; 654 655
Note:
See TracChangeset
for help on using the changeset viewer.