VirtualBox

source: vbox/trunk/src/VBox/Frontends/VirtualBox/src/runtime/UISession.cpp@ 26997

Last change on this file since 26997 was 26997, checked in by vboxsync, 15 years ago

FE/Qt4: New running VM core: win build fix #2.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 36.4 KB
Line 
1/* $Id: UISession.cpp 26997 2010-03-03 16:06:52Z vboxsync $ */
2/** @file
3 *
4 * VBox frontends: Qt GUI ("VirtualBox"):
5 * UISession stuff implementation
6 */
7
8/*
9 * Copyright (C) 2010 Sun Microsystems, Inc.
10 *
11 * This file is part of VirtualBox Open Source Edition (OSE), as
12 * available from http://www.virtualbox.org. This file is free software;
13 * you can redistribute it and/or modify it under the terms of the GNU
14 * General Public License (GPL) as published by the Free Software
15 * Foundation, in version 2 as it comes in the "COPYING" file of the
16 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
17 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
18 *
19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
20 * Clara, CA 95054 USA or visit http://www.sun.com if you need
21 * additional information or have any questions.
22 */
23
24/* Global inclues */
25#include <QApplication>
26#include <QWidget>
27
28/* Local includes */
29#include "UISession.h"
30#include "UIMachine.h"
31#include "UIActionsPool.h"
32#include "UIMachineLogic.h"
33#include "UIMachineWindow.h"
34#include "UIMachineMenuBar.h"
35#include "VBoxProblemReporter.h"
36
37#ifdef Q_WS_X11
38# include <QX11Info>
39# ifndef VBOX_WITHOUT_XCURSOR
40# include <X11/Xcursor/Xcursor.h>
41# endif
42#endif
43
44#if defined (Q_WS_MAC)
45# include "VBoxUtils.h"
46#endif
47
48/* Guest mouse pointer shape change event: */
49class UIMousePointerShapeChangeEvent : public QEvent
50{
51public:
52
53 UIMousePointerShapeChangeEvent(bool bIsVisible, bool bIsAlpha, uint uXHot, uint uYHot, uint uWidth, uint uHeight, const uchar *pShape)
54 : QEvent((QEvent::Type)UIConsoleEventType_MousePointerShapeChange)
55 , m_bIsVisible(bIsVisible), m_bIsAlpha(bIsAlpha), m_uXHot(uXHot), m_uYHot(uYHot), m_uWidth(uWidth), m_uHeight(uHeight), m_pData(0)
56 {
57 uint dataSize = ((((m_uWidth + 7) / 8 * m_uHeight) + 3) & ~3) + m_uWidth * 4 * m_uHeight;
58 if (pShape)
59 {
60 m_pData = new uchar[dataSize];
61 memcpy((void*)m_pData, (void*)pShape, dataSize);
62 }
63 }
64
65 virtual ~UIMousePointerShapeChangeEvent()
66 {
67 if (m_pData) delete[] m_pData;
68 }
69
70 bool isVisible() const { return m_bIsVisible; }
71 bool hasAlpha() const { return m_bIsAlpha; }
72 uint xHot() const { return m_uXHot; }
73 uint yHot() const { return m_uYHot; }
74 uint width() const { return m_uWidth; }
75 uint height() const { return m_uHeight; }
76 const uchar *shapeData() const { return m_pData; }
77
78private:
79
80 bool m_bIsVisible, m_bIsAlpha;
81 uint m_uXHot, m_uYHot, m_uWidth, m_uHeight;
82 const uchar *m_pData;
83};
84
85/* Guest mouse absolute positioning capability change event: */
86class UIMouseCapabilityChangeEvent : public QEvent
87{
88public:
89
90 UIMouseCapabilityChangeEvent(bool bSupportsAbsolute, bool bSupportsRelative, bool bNeedsHostCursor)
91 : QEvent((QEvent::Type)UIConsoleEventType_MouseCapabilityChange)
92 , m_bSupportsAbsolute(bSupportsAbsolute), m_bSupportsRelative(bSupportsRelative), m_bNeedsHostCursor(bNeedsHostCursor) {}
93
94 bool supportsAbsolute() const { return m_bSupportsAbsolute; }
95 bool supportsRelative() const { return m_bSupportsRelative; }
96 bool needsHostCursor() const { return m_bNeedsHostCursor; }
97
98private:
99
100 bool m_bSupportsAbsolute;
101 bool m_bSupportsRelative;
102 bool m_bNeedsHostCursor;
103};
104
105/* Keyboard LEDs change event: */
106class UIKeyboardLedsChangeEvent : public QEvent
107{
108public:
109
110 UIKeyboardLedsChangeEvent(bool bNumLock, bool bCapsLock, bool bScrollLock)
111 : QEvent((QEvent::Type)UIConsoleEventType_KeyboardLedsChange)
112 , m_bNumLock(bNumLock), m_bCapsLock(bCapsLock), m_bScrollLock(bScrollLock) {}
113
114 bool numLock() const { return m_bNumLock; }
115 bool capsLock() const { return m_bCapsLock; }
116 bool scrollLock() const { return m_bScrollLock; }
117
118private:
119
120 bool m_bNumLock;
121 bool m_bCapsLock;
122 bool m_bScrollLock;
123};
124
125/* Machine state change event: */
126class UIStateChangeEvent : public QEvent
127{
128public:
129
130 UIStateChangeEvent(KMachineState machineState)
131 : QEvent((QEvent::Type)UIConsoleEventType_StateChange)
132 , m_machineState(machineState) {}
133
134 KMachineState machineState() const { return m_machineState; }
135
136private:
137
138 KMachineState m_machineState;
139};
140
141/* Guest Additions state change event: */
142class UIAdditionsStateChangeEvent : public QEvent
143{
144public:
145
146 UIAdditionsStateChangeEvent()
147 : QEvent((QEvent::Type)UIConsoleEventType_AdditionsStateChange) {}
148};
149
150/* Network adapter change event: */
151class UINetworkAdapterChangeEvent : public QEvent
152{
153public:
154
155 UINetworkAdapterChangeEvent(const CNetworkAdapter &networkAdapter)
156 : QEvent((QEvent::Type)UIConsoleEventType_NetworkAdapterChange)
157 , m_networkAdapter(networkAdapter) {}
158
159 const CNetworkAdapter& networkAdapter() { return m_networkAdapter; }
160
161private:
162
163 const CNetworkAdapter m_networkAdapter;
164};
165
166/* Serial port change event: */
167class UISerialPortChangeEvent : public QEvent
168{
169public:
170
171 UISerialPortChangeEvent(const CSerialPort &serialPort)
172 : QEvent((QEvent::Type)UIConsoleEventType_SerialPortChange)
173 , m_serialPort(serialPort) {}
174
175 const CSerialPort& serialPort() { return m_serialPort; }
176
177private:
178
179 const CSerialPort m_serialPort;
180};
181
182/* Parallel port change event: */
183class UIParallelPortChangeEvent : public QEvent
184{
185public:
186
187 UIParallelPortChangeEvent(const CParallelPort &parallelPort)
188 : QEvent((QEvent::Type)UIConsoleEventType_ParallelPortChange)
189 , m_parallelPort(parallelPort) {}
190
191 const CParallelPort& parallelPort() { return m_parallelPort; }
192
193private:
194
195 const CParallelPort m_parallelPort;
196};
197
198/* Storage controller change event: */
199class UIStorageControllerChangeEvent : public QEvent
200{
201public:
202
203 UIStorageControllerChangeEvent()
204 : QEvent((QEvent::Type)UIConsoleEventType_StorageControllerChange) {}
205};
206
207/* Storage medium change event: */
208class UIMediumChangeEvent : public QEvent
209{
210public:
211
212 UIMediumChangeEvent(const CMediumAttachment &mediumAttachment)
213 : QEvent((QEvent::Type)UIConsoleEventType_MediumChange)
214 , m_mediumAttachment(mediumAttachment) {}
215 const CMediumAttachment& mediumAttachment() { return m_mediumAttachment; }
216
217private:
218
219 const CMediumAttachment m_mediumAttachment;
220};
221
222/* CPU change event: */
223class UICPUChangeEvent : public QEvent
224{
225public:
226
227 UICPUChangeEvent(ulong uCPU, bool bRemove)
228 : QEvent((QEvent::Type)UIConsoleEventType_CPUChange)
229 , m_uCPU(uCPU), m_bRemove(bRemove) {}
230
231 ulong cpu() const { return m_uCPU; }
232 bool remove() const { return m_bRemove; }
233
234private:
235
236 ulong m_uCPU;
237 bool m_bRemove;
238};
239
240/* VRDP server change event: */
241class UIVRDPServerChangeEvent : public QEvent
242{
243public:
244
245 UIVRDPServerChangeEvent()
246 : QEvent((QEvent::Type)UIConsoleEventType_VRDPServerChange) {}
247};
248
249/* Remote display info change event: */
250class UIRemoteDisplayInfoChangeEvent : public QEvent
251{
252public:
253
254 UIRemoteDisplayInfoChangeEvent()
255 : QEvent((QEvent::Type)UIConsoleEventType_RemoteDisplayInfoChange) {}
256};
257
258/* USB controller change event: */
259class UIUSBControllerChangeEvent : public QEvent
260{
261public:
262
263 UIUSBControllerChangeEvent()
264 : QEvent((QEvent::Type)UIConsoleEventType_USBControllerChange) {}
265};
266
267/* USB device state change event: */
268class UIUSBDeviceUIStateChangeEvent : public QEvent
269{
270public:
271
272 UIUSBDeviceUIStateChangeEvent(const CUSBDevice &device, bool bAttached, const CVirtualBoxErrorInfo &error)
273 : QEvent((QEvent::Type)UIConsoleEventType_USBDeviceStateChange)
274 , m_device(device), m_bAttached(bAttached), m_error(error) {}
275
276 const CUSBDevice& device() const { return m_device; }
277 bool attached() const { return m_bAttached; }
278 const CVirtualBoxErrorInfo& error() const { return m_error; }
279
280private:
281
282 const CUSBDevice m_device;
283 bool m_bAttached;
284 const CVirtualBoxErrorInfo m_error;
285};
286
287/* Shared folder change event: */
288class UISharedFolderChangeEvent : public QEvent
289{
290public:
291
292 UISharedFolderChangeEvent()
293 : QEvent((QEvent::Type)UIConsoleEventType_SharedFolderChange) {}
294};
295
296/* VM Runtime error event: */
297class UIRuntimeErrorEvent : public QEvent
298{
299public:
300
301 UIRuntimeErrorEvent(bool bFatal, const QString &strErrorID, const QString &strMessage)
302 : QEvent((QEvent::Type)UIConsoleEventType_RuntimeError)
303 , m_bFatal(bFatal), m_strErrorID(strErrorID), m_strMessage(strMessage) {}
304
305 bool fatal() const { return m_bFatal; }
306 QString errorID() const { return m_strErrorID; }
307 QString message() const { return m_strMessage; }
308
309private:
310
311 bool m_bFatal;
312 QString m_strErrorID;
313 QString m_strMessage;
314};
315
316/* Can show window event: */
317class UICanUIShowWindowEvent : public QEvent
318{
319public:
320
321 UICanUIShowWindowEvent()
322 : QEvent((QEvent::Type)UIConsoleEventType_CanShowWindow) {}
323};
324
325/* Show window event: */
326class UIShowWindowEvent : public QEvent
327{
328public:
329
330 UIShowWindowEvent()
331 : QEvent((QEvent::Type)UIConsoleEventType_ShowWindow) {}
332};
333
334class UIConsoleCallback : VBOX_SCRIPTABLE_IMPL(IConsoleCallback)
335{
336public:
337
338 UIConsoleCallback(UISession *pEventHandler)
339 : m_pEventHandler(pEventHandler)
340#if defined (Q_WS_WIN)
341 , m_iRefCount(0)
342#endif
343 {
344 }
345
346 virtual ~UIConsoleCallback()
347 {
348 }
349
350 NS_DECL_ISUPPORTS
351
352#if defined (Q_WS_WIN)
353 STDMETHOD_(ULONG, AddRef)()
354 {
355 return ::InterlockedIncrement(&m_iRefCount);
356 }
357 STDMETHOD_(ULONG, Release)()
358 {
359 long iCount = ::InterlockedDecrement(&m_iRefCount);
360 if (iCount == 0)
361 delete this;
362 return iCount;
363 }
364#endif
365
366 VBOX_SCRIPTABLE_DISPATCH_IMPL(IConsoleCallback)
367
368 STDMETHOD(OnMousePointerShapeChange)(BOOL bIsVisible, BOOL bAlpha, ULONG uXHot, ULONG uYHot, ULONG uWidth, ULONG uHeight, BYTE *pShape)
369 {
370 QApplication::postEvent(m_pEventHandler, new UIMousePointerShapeChangeEvent(bIsVisible, bAlpha, uXHot, uYHot, uWidth, uHeight, pShape));
371 return S_OK;
372 }
373
374 STDMETHOD(OnMouseCapabilityChange)(BOOL bSupportsAbsolute, BOOL bSupportsRelative, BOOL bNeedHostCursor)
375 {
376 QApplication::postEvent(m_pEventHandler, new UIMouseCapabilityChangeEvent(bSupportsAbsolute, bSupportsRelative, bNeedHostCursor));
377 return S_OK;
378 }
379
380 STDMETHOD(OnKeyboardLedsChange)(BOOL bNumLock, BOOL bCapsLock, BOOL bScrollLock)
381 {
382 QApplication::postEvent(m_pEventHandler, new UIKeyboardLedsChangeEvent(bNumLock, bCapsLock, bScrollLock));
383 return S_OK;
384 }
385
386 STDMETHOD(OnStateChange)(MachineState_T machineState)
387 {
388 QApplication::postEvent(m_pEventHandler, new UIStateChangeEvent((KMachineState)machineState));
389 return S_OK;
390 }
391
392 STDMETHOD(OnAdditionsStateChange)()
393 {
394 QApplication::postEvent(m_pEventHandler, new UIAdditionsStateChangeEvent);
395 return S_OK;
396 }
397
398 STDMETHOD(OnNetworkAdapterChange)(INetworkAdapter *pNetworkAdapter)
399 {
400 QApplication::postEvent(m_pEventHandler, new UINetworkAdapterChangeEvent(CNetworkAdapter(pNetworkAdapter)));
401 return S_OK;
402 }
403
404 STDMETHOD(OnSerialPortChange)(ISerialPort *pSerialPort)
405 {
406 QApplication::postEvent(m_pEventHandler, new UISerialPortChangeEvent(CSerialPort(pSerialPort)));
407 return S_OK;
408 }
409
410 STDMETHOD(OnParallelPortChange)(IParallelPort *pParallelPort)
411 {
412 QApplication::postEvent(m_pEventHandler, new UIParallelPortChangeEvent(CParallelPort(pParallelPort)));
413 return S_OK;
414 }
415
416 STDMETHOD(OnStorageControllerChange)()
417 {
418 QApplication::postEvent(m_pEventHandler, new UIStorageControllerChangeEvent);
419 return S_OK;
420 }
421
422 STDMETHOD(OnMediumChange)(IMediumAttachment *pMediumAttachment)
423 {
424 QApplication::postEvent(m_pEventHandler, new UIMediumChangeEvent(CMediumAttachment(pMediumAttachment)));
425 return S_OK;
426 }
427
428 STDMETHOD(OnCPUChange)(ULONG uCPU, BOOL bRemove)
429 {
430 QApplication::postEvent(m_pEventHandler, new UICPUChangeEvent(uCPU, bRemove));
431 return S_OK;
432 }
433
434 STDMETHOD(OnVRDPServerChange)()
435 {
436 QApplication::postEvent(m_pEventHandler, new UIVRDPServerChangeEvent);
437 return S_OK;
438 }
439
440 STDMETHOD(OnRemoteDisplayInfoChange)()
441 {
442 QApplication::postEvent(m_pEventHandler, new UIRemoteDisplayInfoChangeEvent);
443 return S_OK;
444 }
445
446 STDMETHOD(OnUSBControllerChange)()
447 {
448 QApplication::postEvent(m_pEventHandler, new UIUSBControllerChangeEvent);
449 return S_OK;
450 }
451
452 STDMETHOD(OnUSBDeviceStateChange)(IUSBDevice *pDevice, BOOL bAttached, IVirtualBoxErrorInfo *pError)
453 {
454 QApplication::postEvent(m_pEventHandler, new UIUSBDeviceUIStateChangeEvent(CUSBDevice(pDevice), bAttached, CVirtualBoxErrorInfo(pError)));
455 return S_OK;
456 }
457
458 STDMETHOD(OnSharedFolderChange)(Scope_T scope)
459 {
460 NOREF(scope);
461 QApplication::postEvent(m_pEventHandler, new UISharedFolderChangeEvent);
462 return S_OK;
463 }
464
465 STDMETHOD(OnRuntimeError)(BOOL bFatal, IN_BSTR strId, IN_BSTR strMessage)
466 {
467 QApplication::postEvent(m_pEventHandler, new UIRuntimeErrorEvent(bFatal, QString::fromUtf16(strId), QString::fromUtf16(strMessage)));
468 return S_OK;
469 }
470
471 STDMETHOD(OnCanShowWindow)(BOOL *pbCanShow)
472 {
473 if (!pbCanShow)
474 return E_POINTER;
475
476 *pbCanShow = TRUE;
477 return S_OK;
478 }
479
480 STDMETHOD(OnShowWindow)(ULONG64 *puWinId)
481 {
482 if (!puWinId)
483 return E_POINTER;
484
485#if defined (Q_WS_MAC)
486 /* Let's try the simple approach first - grab the focus.
487 * Getting a window out of the dock (minimized or whatever it's called)
488 * needs to be done on the GUI thread, so post it a note: */
489 *puWinId = 0;
490 if (!m_pEventHandler)
491 return S_OK;
492
493 if (::darwinSetFrontMostProcess())
494 QApplication::postEvent(m_pEventHandler, new UIShowWindowEvent);
495 else
496 {
497 /* It failed for some reason, send the other process our PSN so it can try.
498 * (This is just a precaution should Mac OS X start imposing the same sensible
499 * focus stealing restrictions that other window managers implement). */
500 *puWinId = ::darwinGetCurrentProcessId();
501 }
502#else
503 /* Return the ID of the top-level console window. */
504 *puWinId = (ULONG64)m_pEventHandler->winId();
505#endif
506
507 return S_OK;
508 }
509
510private:
511
512 UISession *m_pEventHandler;
513
514#if defined (Q_WS_WIN)
515 long m_iRefCount;
516#endif
517};
518
519#if !defined (Q_WS_WIN)
520NS_DECL_CLASSINFO(UIConsoleCallback)
521NS_IMPL_THREADSAFE_ISUPPORTS1_CI(UIConsoleCallback, IConsoleCallback)
522#endif
523
524UISession::UISession(UIMachine *pMachine, CSession &sessionReference)
525 : QObject(pMachine)
526 /* Base variables: */
527 , m_pMachine(pMachine)
528 , m_session(sessionReference)
529 , m_callback(CConsoleCallback(new UIConsoleCallback(this)))
530 /* Common variables: */
531 , m_pMenuBar(0)
532 , m_machineState(KMachineState_Null)
533#if defined(Q_WS_WIN)
534 , m_alphaCursor(0)
535#endif
536 /* Common flags: */
537 , m_fIsFirstTimeStarted(false)
538 , m_fIsIgnoreRutimeMediumsChanging(false)
539 , m_fIsGuestResizeIgnored(false)
540 /* Guest additions flags: */
541 , m_fIsGuestAdditionsActive(false)
542 , m_fIsGuestSupportsGraphics(false)
543 , m_fIsGuestSupportsSeamless(false)
544 /* Mouse flags: */
545 , m_fNumLock(false)
546 , m_fCapsLock(false)
547 , m_fScrollLock(false)
548 , m_uNumLockAdaptionCnt(2)
549 , m_uCapsLockAdaptionCnt(2)
550 /* Mouse flags: */
551 , m_fIsMouseSupportsAbsolute(false)
552 , m_fIsMouseSupportsRelative(false)
553 , m_fIsMouseHostCursorNeeded(false)
554 , m_fIsMouseCaptured(false)
555 , m_fIsMouseIntegrated(true)
556 , m_fIsValidPointerShapePresent(false)
557 , m_fIsHideHostPointer(true)
558{
559 /* Register console callback: */
560 session().GetConsole().RegisterCallback(m_callback);
561
562 /* Load uisession settings: */
563 loadSessionSettings();
564}
565
566UISession::~UISession()
567{
568 /* Save uisession settings: */
569 saveSessionSettings();
570
571 /* Unregister console callback: */
572 session().GetConsole().UnregisterCallback(m_callback);
573}
574
575UIActionsPool* UISession::actionsPool() const
576{
577 return m_pMachine->actionsPool();
578}
579
580QMenuBar* UISession::newMenuBar()
581{
582 /* */
583 QMenuBar *pMenuBar = m_pMenuBar->createMenuBar(this);
584
585 /* Get uisession machine: */
586 CMachine machine = session().GetConsole().GetMachine();
587
588 /* Availability settings: */
589 {
590 /* USB Stuff: */
591 CUSBController usbController = machine.GetUSBController();
592 if ( usbController.isNull()
593 || !usbController.GetProxyAvailable())
594 {
595 /* Hide USB menu if controller is NULL or no USB proxy available: */
596 uimachine()->actionsPool()->action(UIActionIndex_Menu_USBDevices)->setVisible(false);
597 }
598 else
599 {
600 /* Enable/Disable USB menu depending on USB controller: */
601 uimachine()->actionsPool()->action(UIActionIndex_Menu_USBDevices)->setEnabled(usbController.GetEnabled());
602 }
603 }
604
605 /* Prepare some initial settings: */
606 {
607 /* Initialize CD/FD menus: */
608 int iDevicesCountCD = 0;
609 int iDevicesCountFD = 0;
610 const CMediumAttachmentVector &attachments = machine.GetMediumAttachments();
611 foreach (const CMediumAttachment &attachment, attachments)
612 {
613 if (attachment.GetType() == KDeviceType_DVD)
614 ++ iDevicesCountCD;
615 if (attachment.GetType() == KDeviceType_Floppy)
616 ++ iDevicesCountFD;
617 }
618 QAction *pOpticalDevicesMenu = uimachine()->actionsPool()->action(UIActionIndex_Menu_OpticalDevices);
619 QAction *pFloppyDevicesMenu = uimachine()->actionsPool()->action(UIActionIndex_Menu_FloppyDevices);
620 pOpticalDevicesMenu->setData(iDevicesCountCD);
621 pOpticalDevicesMenu->setVisible(iDevicesCountCD);
622 pFloppyDevicesMenu->setData(iDevicesCountFD);
623 pFloppyDevicesMenu->setVisible(iDevicesCountFD);
624 }
625
626 return pMenuBar;
627}
628
629bool UISession::setPause(bool fOn)
630{
631 if (isPaused() == fOn)
632 return true;
633
634 CConsole console = session().GetConsole();
635
636 if (fOn)
637 console.Pause();
638 else
639 console.Resume();
640
641 bool ok = console.isOk();
642 if (!ok)
643 {
644 if (fOn)
645 vboxProblem().cannotPauseMachine(console);
646 else
647 vboxProblem().cannotResumeMachine(console);
648 }
649
650 return ok;
651}
652
653void UISession::sltCloseVirtualSession()
654{
655 m_pMachine->closeVirtualMachine();
656}
657
658bool UISession::event(QEvent *pEvent)
659{
660 switch (pEvent->type())
661 {
662 case UIConsoleEventType_MousePointerShapeChange:
663 {
664 /* Convert to mouse shape change event: */
665 UIMousePointerShapeChangeEvent *pConsoleEvent = static_cast<UIMousePointerShapeChangeEvent*>(pEvent);
666
667 /* Remember if we should show cursor: */
668 m_fIsHideHostPointer = !pConsoleEvent->isVisible();
669
670 /* Cache shape dataif present: */
671 if (pConsoleEvent->shapeData())
672 setPointerShape(pConsoleEvent->shapeData(), pConsoleEvent->hasAlpha(),
673 pConsoleEvent->xHot(), pConsoleEvent->yHot(),
674 pConsoleEvent->width(), pConsoleEvent->height());
675
676 /* Notify listeners about mouse capability changed: */
677 emit sigMousePointerShapeChange();
678
679 /* Accept event: */
680 pEvent->accept();
681 return true;
682 }
683
684 case UIConsoleEventType_MouseCapabilityChange:
685 {
686 /* Convert to mouse capability event: */
687 UIMouseCapabilityChangeEvent *pConsoleEvent = static_cast<UIMouseCapabilityChangeEvent*>(pEvent);
688
689 /* Check if something had changed: */
690 if (m_fIsMouseSupportsAbsolute != pConsoleEvent->supportsAbsolute() ||
691 m_fIsMouseSupportsRelative != pConsoleEvent->supportsRelative() ||
692 m_fIsMouseHostCursorNeeded != pConsoleEvent->needsHostCursor())
693 {
694 /* Store new data: */
695 m_fIsMouseSupportsAbsolute = pConsoleEvent->supportsAbsolute();
696 m_fIsMouseSupportsRelative = pConsoleEvent->supportsRelative();
697 m_fIsMouseHostCursorNeeded = pConsoleEvent->needsHostCursor();
698
699 /* Notify listeners about mouse capability changed: */
700 emit sigMouseCapabilityChange();
701 }
702
703 /* Accept event: */
704 pEvent->accept();
705 return true;
706 }
707
708 case UIConsoleEventType_KeyboardLedsChange:
709 {
710 /* Convert to keyboard LEDs change event: */
711 UIKeyboardLedsChangeEvent *pConsoleEvent = static_cast<UIKeyboardLedsChangeEvent*>(pEvent);
712
713 /* Check if something had changed: */
714 if (m_fNumLock != pConsoleEvent->numLock() ||
715 m_fCapsLock != pConsoleEvent->capsLock() ||
716 m_fScrollLock != pConsoleEvent->scrollLock())
717 {
718 /* Store new num lock data: */
719 if (m_fNumLock != pConsoleEvent->numLock())
720 {
721 m_fNumLock = pConsoleEvent->numLock();
722 m_uNumLockAdaptionCnt = 2;
723 }
724
725 /* Store new caps lock data: */
726 if (m_fCapsLock != pConsoleEvent->capsLock())
727 {
728 m_fCapsLock = pConsoleEvent->capsLock();
729 m_uCapsLockAdaptionCnt = 2;
730 }
731
732 /* Store new scroll lock data: */
733 if (m_fScrollLock != pConsoleEvent->scrollLock())
734 {
735 m_fScrollLock = pConsoleEvent->scrollLock();
736 }
737
738 /* Notify listeners about mouse capability changed: */
739 emit sigKeyboardLedsChange();
740 }
741
742 /* Accept event: */
743 pEvent->accept();
744 return true;
745 }
746
747 case UIConsoleEventType_StateChange:
748 {
749 /* Convert to machine state event: */
750 UIStateChangeEvent *pConsoleEvent = static_cast<UIStateChangeEvent*>(pEvent);
751
752 /* Check if something had changed: */
753 if (m_machineState != pConsoleEvent->machineState())
754 {
755 /* Store new data: */
756 m_machineState = pConsoleEvent->machineState();
757
758 /* Notify listeners about machine state changed: */
759 emit sigMachineStateChange();
760 }
761
762 /* Accept event: */
763 pEvent->accept();
764 return true;
765 }
766
767 case UIConsoleEventType_AdditionsStateChange:
768 {
769 /* Get our guest: */
770 CGuest guest = session().GetConsole().GetGuest();
771
772 /* Variable flags: */
773 bool fIsGuestAdditionsActive = guest.GetAdditionsActive();
774 bool fIsGuestSupportsGraphics = guest.GetSupportsGraphics();
775 bool fIsGuestSupportsSeamless = guest.GetSupportsSeamless();
776
777 /* Check if something had changed: */
778 if (m_fIsGuestAdditionsActive != fIsGuestAdditionsActive ||
779 m_fIsGuestSupportsGraphics != fIsGuestSupportsGraphics ||
780 m_fIsGuestSupportsSeamless != fIsGuestSupportsSeamless)
781 {
782 /* Store new data: */
783 m_fIsGuestAdditionsActive = fIsGuestAdditionsActive;
784 m_fIsGuestSupportsGraphics = fIsGuestSupportsGraphics;
785 m_fIsGuestSupportsSeamless = fIsGuestSupportsSeamless;
786
787 /* Notify listeners about guest additions state changed: */
788 emit sigAdditionsStateChange();
789 }
790
791 /* Accept event: */
792 pEvent->accept();
793 return true;
794 }
795
796 case UIConsoleEventType_NetworkAdapterChange:
797 {
798 UINetworkAdapterChangeEvent *pConsoleEvent = static_cast<UINetworkAdapterChangeEvent*>(pEvent);
799 emit sigNetworkAdapterChange(pConsoleEvent->networkAdapter());
800 return true;
801 }
802
803 case UIConsoleEventType_SerialPortChange:
804 {
805 UISerialPortChangeEvent *pConsoleEvent = static_cast<UISerialPortChangeEvent*>(pEvent);
806 emit sigSerialPortChange(pConsoleEvent->serialPort());
807 return true;
808 }
809
810 case UIConsoleEventType_ParallelPortChange:
811 {
812 UIParallelPortChangeEvent *pConsoleEvent = static_cast<UIParallelPortChangeEvent*>(pEvent);
813 emit sigParallelPortChange(pConsoleEvent->parallelPort());
814 return true;
815 }
816
817 case UIConsoleEventType_StorageControllerChange:
818 {
819 emit sigStorageControllerChange();
820 return true;
821 }
822
823 case UIConsoleEventType_MediumChange:
824 {
825 UIMediumChangeEvent *pConsoleEvent = static_cast<UIMediumChangeEvent*>(pEvent);
826 emit sigMediumChange(pConsoleEvent->mediumAttachment());
827 return true;
828 }
829
830 case UIConsoleEventType_CPUChange:
831 {
832 UICPUChangeEvent *pConsoleEvent = static_cast<UICPUChangeEvent*>(pEvent);
833 emit sigCPUChange(pConsoleEvent->cpu(), pConsoleEvent->remove());
834 return true;
835 }
836
837 case UIConsoleEventType_VRDPServerChange:
838 {
839 emit sigVRDPServerChange();
840 return true;
841 }
842
843 case UIConsoleEventType_RemoteDisplayInfoChange:
844 {
845 emit sigRemoteDisplayInfoChange();
846 return true;
847 }
848
849 case UIConsoleEventType_USBControllerChange:
850 {
851 emit sigUSBControllerChange();
852 return true;
853 }
854
855 case UIConsoleEventType_USBDeviceStateChange:
856 {
857 UIUSBDeviceUIStateChangeEvent *pConsoleEvent = static_cast<UIUSBDeviceUIStateChangeEvent*>(pEvent);
858 emit sigUSBDeviceStateChange(pConsoleEvent->device(), pConsoleEvent->attached(), pConsoleEvent->error());
859 return true;
860 }
861
862 case UIConsoleEventType_SharedFolderChange:
863 {
864 emit sigSharedFolderChange();
865 return true;
866 }
867
868 case UIConsoleEventType_RuntimeError:
869 {
870 UIRuntimeErrorEvent *pConsoleEvent = static_cast<UIRuntimeErrorEvent*>(pEvent);
871 emit sigRuntimeError(pConsoleEvent->fatal(), pConsoleEvent->errorID(), pConsoleEvent->message());
872 return true;
873 }
874
875#ifdef Q_WS_MAC
876 /* posted OnShowWindow */
877 case UIConsoleEventType_ShowWindow:
878 {
879 /* Dunno what Qt3 thinks a window that has minimized to the dock
880 * should be - it is not hidden, neither is it minimized. OTOH it is
881 * marked shown and visible, but not activated. This latter isn't of
882 * much help though, since at this point nothing is marked activated.
883 * I might have overlooked something, but I'm buggered what if I know
884 * what. So, I'll just always show & activate the stupid window to
885 * make it get out of the dock when the user wishes to show a VM. */
886#if 0
887 // TODO_NEW_CORE
888 window()->show();
889 window()->activateWindow();
890#endif
891 return true;
892 }
893#endif
894
895 default:
896 break;
897 }
898 return QObject::event(pEvent);
899}
900
901void UISession::loadSessionSettings()
902{
903 m_pMenuBar = new UIMachineMenuBar;
904
905 /* Get uisession machine: */
906 CMachine machine = session().GetConsole().GetMachine();
907
908 /* Availability settings: */
909 {
910 /* VRDP Stuff: */
911 CVRDPServer vrdpServer = machine.GetVRDPServer();
912 if (vrdpServer.isNull())
913 {
914 /* Hide VRDP Action: */
915 uimachine()->actionsPool()->action(UIActionIndex_Toggle_VRDP)->setVisible(false);
916 }
917 }
918
919
920 /* Load extra-data settings: */
921 {
922 /* Temporary: */
923 QString strSettings;
924
925 /* Is there shoul be First RUN Wizard? */
926 strSettings = machine.GetExtraData(VBoxDefs::GUI_FirstRun);
927 if (strSettings == "yes")
928 m_fIsFirstTimeStarted = true;
929
930 /* Ignore mediums mounted at runtime? */
931 strSettings = machine.GetExtraData(VBoxDefs::GUI_SaveMountedAtRuntime);
932 if (strSettings == "no")
933 m_fIsIgnoreRutimeMediumsChanging = true;
934
935 /* Should guest autoresize? */
936 strSettings = machine.GetExtraData(VBoxDefs::GUI_AutoresizeGuest);
937 QAction *pGuestAutoresizeSwitch = uimachine()->actionsPool()->action(UIActionIndex_Toggle_GuestAutoresize);
938 pGuestAutoresizeSwitch->blockSignals(true);
939 pGuestAutoresizeSwitch->setChecked(strSettings != "off");
940 pGuestAutoresizeSwitch->blockSignals(false);
941 }
942}
943
944void UISession::saveSessionSettings()
945{
946 /* Get uisession machine: */
947 CMachine machine = session().GetConsole().GetMachine();
948
949 /* Save extra-data settings: */
950 {
951 /* Disable First RUN Wizard for the since now: */
952 machine.SetExtraData(VBoxDefs::GUI_FirstRun, QString());
953
954 /* Remember if guest should autoresize: */
955 machine.SetExtraData(VBoxDefs::GUI_AutoresizeGuest,
956 uimachine()->actionsPool()->action(UIActionIndex_Toggle_GuestAutoresize)->isChecked() ?
957 QString() : "off");
958
959 // TODO: Move to fullscreen/seamless logic:
960 //machine.SetExtraData(VBoxDefs::GUI_MiniToolBarAutoHide, mMiniToolBar->isAutoHide() ? "on" : "off");
961 }
962
963 delete m_pMenuBar;
964 m_pMenuBar = 0;
965}
966
967WId UISession::winId() const
968{
969 return uimachine()->machineLogic()->mainMachineWindow()->machineWindow()->winId();
970}
971
972void UISession::setPointerShape(const uchar *pShapeData, bool fHasAlpha,
973 uint uXHot, uint uYHot, uint uWidth, uint uHeight)
974{
975 AssertMsg(pShapeData, ("Shape data must not be NULL!\n"));
976
977 m_fIsValidPointerShapePresent = false;
978 const uchar *srcAndMaskPtr = pShapeData;
979 uint andMaskSize = (uWidth + 7) / 8 * uHeight;
980 const uchar *srcShapePtr = pShapeData + ((andMaskSize + 3) & ~3);
981 uint srcShapePtrScan = uWidth * 4;
982
983#if defined (Q_WS_WIN)
984
985 BITMAPV5HEADER bi;
986 HBITMAP hBitmap;
987 void *lpBits;
988
989 ::ZeroMemory(&bi, sizeof (BITMAPV5HEADER));
990 bi.bV5Size = sizeof(BITMAPV5HEADER);
991 bi.bV5Width = uWidth;
992 bi.bV5Height = - (LONG)uHeight;
993 bi.bV5Planes = 1;
994 bi.bV5BitCount = 32;
995 bi.bV5Compression = BI_BITFIELDS;
996 bi.bV5RedMask = 0x00FF0000;
997 bi.bV5GreenMask = 0x0000FF00;
998 bi.bV5BlueMask = 0x000000FF;
999 if (fHasAlpha)
1000 bi.bV5AlphaMask = 0xFF000000;
1001 else
1002 bi.bV5AlphaMask = 0;
1003
1004 HDC hdc = GetDC(NULL);
1005
1006 /* Create the DIB section with an alpha channel: */
1007 hBitmap = CreateDIBSection(hdc, (BITMAPINFO *)&bi, DIB_RGB_COLORS, (void **)&lpBits, NULL, (DWORD) 0);
1008
1009 ReleaseDC(NULL, hdc);
1010
1011 HBITMAP hMonoBitmap = NULL;
1012 if (fHasAlpha)
1013 {
1014 /* Create an empty mask bitmap: */
1015 hMonoBitmap = CreateBitmap(uWidth, uHeight, 1, 1, NULL);
1016 }
1017 else
1018 {
1019 /* Word aligned AND mask. Will be allocated and created if necessary. */
1020 uint8_t *pu8AndMaskWordAligned = NULL;
1021
1022 /* Width in bytes of the original AND mask scan line. */
1023 uint32_t cbAndMaskScan = (uWidth + 7) / 8;
1024
1025 if (cbAndMaskScan & 1)
1026 {
1027 /* Original AND mask is not word aligned. */
1028
1029 /* Allocate memory for aligned AND mask. */
1030 pu8AndMaskWordAligned = (uint8_t *)RTMemTmpAllocZ((cbAndMaskScan + 1) * uHeight);
1031
1032 Assert(pu8AndMaskWordAligned);
1033
1034 if (pu8AndMaskWordAligned)
1035 {
1036 /* According to MSDN the padding bits must be 0.
1037 * Compute the bit mask to set padding bits to 0 in the last byte of original AND mask. */
1038 uint32_t u32PaddingBits = cbAndMaskScan * 8 - uWidth;
1039 Assert(u32PaddingBits < 8);
1040 uint8_t u8LastBytesPaddingMask = (uint8_t)(0xFF << u32PaddingBits);
1041
1042 Log(("u8LastBytesPaddingMask = %02X, aligned w = %d, width = %d, cbAndMaskScan = %d\n",
1043 u8LastBytesPaddingMask, (cbAndMaskScan + 1) * 8, uWidth, cbAndMaskScan));
1044
1045 uint8_t *src = (uint8_t *)srcAndMaskPtr;
1046 uint8_t *dst = pu8AndMaskWordAligned;
1047
1048 unsigned i;
1049 for (i = 0; i < uHeight; i++)
1050 {
1051 memcpy(dst, src, cbAndMaskScan);
1052
1053 dst[cbAndMaskScan - 1] &= u8LastBytesPaddingMask;
1054
1055 src += cbAndMaskScan;
1056 dst += cbAndMaskScan + 1;
1057 }
1058 }
1059 }
1060
1061 /* Create the AND mask bitmap: */
1062 hMonoBitmap = ::CreateBitmap(uWidth, uHeight, 1, 1,
1063 pu8AndMaskWordAligned? pu8AndMaskWordAligned: srcAndMaskPtr);
1064
1065 if (pu8AndMaskWordAligned)
1066 {
1067 RTMemTmpFree(pu8AndMaskWordAligned);
1068 }
1069 }
1070
1071 Assert(hBitmap);
1072 Assert(hMonoBitmap);
1073 if (hBitmap && hMonoBitmap)
1074 {
1075 DWORD *dstShapePtr = (DWORD *) lpBits;
1076
1077 for (uint y = 0; y < uHeight; y ++)
1078 {
1079 memcpy(dstShapePtr, srcShapePtr, srcShapePtrScan);
1080 srcShapePtr += srcShapePtrScan;
1081 dstShapePtr += uWidth;
1082 }
1083
1084 ICONINFO ii;
1085 ii.fIcon = FALSE;
1086 ii.xHotspot = uXHot;
1087 ii.yHotspot = uYHot;
1088 ii.hbmMask = hMonoBitmap;
1089 ii.hbmColor = hBitmap;
1090
1091 HCURSOR hAlphaCursor = CreateIconIndirect(&ii);
1092 Assert(hAlphaCursor);
1093 if (hAlphaCursor)
1094 {
1095 /* Set the new cursor: */
1096 m_cursor = QCursor(hAlphaCursor);
1097 if (m_alphaCursor)
1098 DestroyIcon(m_alphaCursor);
1099 m_alphaCursor = hAlphaCursor;
1100 m_fIsValidPointerShapePresent = true;
1101 }
1102 }
1103
1104 if (hMonoBitmap)
1105 DeleteObject(hMonoBitmap);
1106 if (hBitmap)
1107 DeleteObject(hBitmap);
1108
1109#elif defined (Q_WS_X11) && !defined (VBOX_WITHOUT_XCURSOR)
1110
1111 XcursorImage *img = XcursorImageCreate(uWidth, uHeight);
1112 Assert(img);
1113 if (img)
1114 {
1115 img->xhot = uXHot;
1116 img->yhot = uYHot;
1117
1118 XcursorPixel *dstShapePtr = img->pixels;
1119
1120 for (uint y = 0; y < uHeight; y ++)
1121 {
1122 memcpy (dstShapePtr, srcShapePtr, srcShapePtrScan);
1123
1124 if (!fHasAlpha)
1125 {
1126 /* Convert AND mask to the alpha channel: */
1127 uchar byte = 0;
1128 for (uint x = 0; x < uWidth; x ++)
1129 {
1130 if (!(x % 8))
1131 byte = *(srcAndMaskPtr ++);
1132 else
1133 byte <<= 1;
1134
1135 if (byte & 0x80)
1136 {
1137 /* Linux doesn't support inverted pixels (XOR ops,
1138 * to be exact) in cursor shapes, so we detect such
1139 * pixels and always replace them with black ones to
1140 * make them visible at least over light colors */
1141 if (dstShapePtr [x] & 0x00FFFFFF)
1142 dstShapePtr [x] = 0xFF000000;
1143 else
1144 dstShapePtr [x] = 0x00000000;
1145 }
1146 else
1147 dstShapePtr [x] |= 0xFF000000;
1148 }
1149 }
1150
1151 srcShapePtr += srcShapePtrScan;
1152 dstShapePtr += uWidth;
1153 }
1154
1155 /* Set the new cursor: */
1156 m_cursor = QCursor(XcursorImageLoadCursor(QX11Info::display(), img));
1157 m_fIsValidPointerShapePresent = true;
1158
1159 XcursorImageDestroy(img);
1160 }
1161
1162#elif defined(Q_WS_MAC)
1163
1164 /* Create a ARGB image out of the shape data. */
1165 QImage image (uWidth, uHeight, QImage::Format_ARGB32);
1166 const uint8_t* pbSrcMask = static_cast<const uint8_t*> (srcAndMaskPtr);
1167 unsigned cbSrcMaskLine = RT_ALIGN (uWidth, 8) / 8;
1168 for (unsigned int y = 0; y < uHeight; ++y)
1169 {
1170 for (unsigned int x = 0; x < uWidth; ++x)
1171 {
1172 unsigned int color = ((unsigned int*)srcShapePtr)[y*uWidth+x];
1173 /* If the alpha channel isn't in the shape data, we have to
1174 * create them from the and-mask. This is a bit field where 1
1175 * represent transparency & 0 opaque respectively. */
1176 if (!fHasAlpha)
1177 {
1178 if (!(pbSrcMask[x / 8] & (1 << (7 - (x % 8)))))
1179 color |= 0xff000000;
1180 else
1181 {
1182 /* This isn't quite right, but it's the best we can do I think... */
1183 if (color & 0x00ffffff)
1184 color = 0xff000000;
1185 else
1186 color = 0x00000000;
1187 }
1188 }
1189 image.setPixel (x, y, color);
1190 }
1191 /* Move one scanline forward. */
1192 pbSrcMask += cbSrcMaskLine;
1193 }
1194
1195 /* Set the new cursor: */
1196 m_cursor = QCursor(QPixmap::fromImage(image), uXHot, uYHot);
1197 m_fIsValidPointerShapePresent = true;
1198 NOREF(srcShapePtrScan);
1199
1200#else
1201
1202# warning "port me"
1203
1204#endif
1205}
1206
Note: See TracBrowser for help on using the repository browser.

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