summaryrefslogtreecommitdiff
path: root/src/VBox/Frontends/VirtualBox/src
diff options
context:
space:
mode:
Diffstat (limited to 'src/VBox/Frontends/VirtualBox/src')
-rw-r--r--src/VBox/Frontends/VirtualBox/src/VBoxConsoleView.cpp38
-rw-r--r--src/VBox/Frontends/VirtualBox/src/VBoxFBQuartz2D.cpp144
-rw-r--r--src/VBox/Frontends/VirtualBox/src/VBoxProblemReporter.cpp26
-rw-r--r--src/VBox/Frontends/VirtualBox/src/VBoxVMSettingsUSB.cpp1
-rw-r--r--src/VBox/Frontends/VirtualBox/src/main.cpp2
5 files changed, 194 insertions, 17 deletions
diff --git a/src/VBox/Frontends/VirtualBox/src/VBoxConsoleView.cpp b/src/VBox/Frontends/VirtualBox/src/VBoxConsoleView.cpp
index 3eefb3908..8231ff5ce 100644
--- a/src/VBox/Frontends/VirtualBox/src/VBoxConsoleView.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/VBoxConsoleView.cpp
@@ -1910,8 +1910,18 @@ bool VBoxConsoleView::winLowKeyboardEvent (UINT msg, const KBDLLHOOKSTRUCT &even
* the VK_LCONTROL vkey with curious 0x21D scan code (seems to be necessary
* to specially treat ALT_GR to enter additional chars to regular apps).
* These events are definitely unwanted in VM, so filter them out. */
+ /* Note (michael): it also sometimes sends the VK_CAPITAL vkey with scan
+ * code 0x23a. If this is not passed through then it is impossible to
+ * cancel CapsLock on a French keyboard. I didn't find any other examples
+ * of these strange events. Let's hope we are not missing anything else
+ * of importance! */
if (hasFocus() && (event.scanCode & ~0xFF))
- return true;
+ {
+ if (event.vkCode == VK_CAPITAL)
+ return false;
+ else
+ return true;
+ }
if (!mKbdCaptured)
return false;
@@ -2051,7 +2061,7 @@ bool VBoxConsoleView::winEvent (MSG *aMsg, long* /* aResult */)
/* These special keys have to be handled by Windows as well to update the
* internal modifier state and to enable/disable the keyboard LED */
- if (vkey == VK_NUMLOCK || vkey == VK_CAPITAL)
+ if (vkey == VK_NUMLOCK || vkey == VK_CAPITAL || vkey == VK_LSHIFT || vkey == VK_RSHIFT)
return false;
return result;
@@ -2530,6 +2540,14 @@ void VBoxConsoleView::fixModifierState (LONG *codes, uint *count)
muCapsLockAdaptionCnt--;
codes[(*count)++] = 0x3a;
codes[(*count)++] = 0x3a | 0x80;
+ /* Some keyboard layouts require shift to be pressed to break
+ * capslock. For simplicity, only do this if shift is not
+ * already held down. */
+ if (mCapsLock && !(mPressedKeys [0x2a] & IsKeyPressed))
+ {
+ codes[(*count)++] = 0x2a;
+ codes[(*count)++] = 0x2a | 0x80;
+ }
}
#elif defined(Q_WS_WIN32)
@@ -2545,6 +2563,14 @@ void VBoxConsoleView::fixModifierState (LONG *codes, uint *count)
muCapsLockAdaptionCnt--;
codes[(*count)++] = 0x3a;
codes[(*count)++] = 0x3a | 0x80;
+ /* Some keyboard layouts require shift to be pressed to break
+ * capslock. For simplicity, only do this if shift is not
+ * already held down. */
+ if (mCapsLock && !(mPressedKeys [0x2a] & IsKeyPressed))
+ {
+ codes[(*count)++] = 0x2a;
+ codes[(*count)++] = 0x2a | 0x80;
+ }
}
#elif defined (Q_WS_MAC)
@@ -2555,6 +2581,14 @@ void VBoxConsoleView::fixModifierState (LONG *codes, uint *count)
muCapsLockAdaptionCnt--;
codes[(*count)++] = 0x3a;
codes[(*count)++] = 0x3a | 0x80;
+ /* Some keyboard layouts require shift to be pressed to break
+ * capslock. For simplicity, only do this if shift is not
+ * already held down. */
+ if (mCapsLock && !(mPressedKeys [0x2a] & IsKeyPressed))
+ {
+ codes[(*count)++] = 0x2a;
+ codes[(*count)++] = 0x2a | 0x80;
+ }
}
#else
diff --git a/src/VBox/Frontends/VirtualBox/src/VBoxFBQuartz2D.cpp b/src/VBox/Frontends/VirtualBox/src/VBoxFBQuartz2D.cpp
index 06c2663c1..1ec6d820d 100644
--- a/src/VBox/Frontends/VirtualBox/src/VBoxFBQuartz2D.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/VBoxFBQuartz2D.cpp
@@ -33,7 +33,12 @@
#include "VBoxConsoleWnd.h"
#include "VBoxIChatTheaterWrapper.h"
+#include <QDesktopWidget>
+
+#include "iprt/system.h"
+
//#define COMP_WITH_SHADOW
+//#define OVERLAY_CLIPRECTS
/** @class VBoxQuartz2DFrameBuffer
*
@@ -41,24 +46,75 @@
* interface and uses Apples Quartz2D to store and render VM display data.
*/
-VBoxQuartz2DFrameBuffer::VBoxQuartz2DFrameBuffer (VBoxConsoleView *aView) :
- VBoxFrameBuffer(aView),
- mDataAddress(NULL),
- mBitmapData(NULL),
- mPixelFormat(FramebufferPixelFormat_FOURCC_RGB),
- mImage(NULL),
- mRegion (NULL),
- mRegionUnused (NULL)
+#ifndef QT_MAC_USE_COCOA
+static OSStatus darwinSNWindowHandler (EventHandlerCallRef aInHandlerCallRef, EventRef aInEvent, void *aInUserData)
+{
+ if ( aInUserData
+ && ::GetEventClass (aInEvent) == kEventClassWindow
+ && ::GetEventKind (aInEvent) == kEventWindowBoundsChanged)
+ static_cast<VBoxQuartz2DFrameBuffer *> (aInUserData)->testAndSetSNCarbonFix();
+
+ return ::CallNextEventHandler (aInHandlerCallRef, aInEvent);
+}
+#endif /* QT_MAC_USE_COCOA */
+
+VBoxQuartz2DFrameBuffer::VBoxQuartz2DFrameBuffer (VBoxConsoleView *aView)
+ : VBoxFrameBuffer(aView)
+ , mDataAddress(NULL)
+ , mBitmapData(NULL)
+ , mPixelFormat(FramebufferPixelFormat_FOURCC_RGB)
+ , mImage(NULL)
+ , mRegion (NULL)
+ , mRegionUnused (NULL)
+#ifndef QT_MAC_USE_COCOA
+ , mSnowLeoCarbonFix (false)
+ , mDarwinSNWindowHandlerRef (NULL)
+#endif /* QT_MAC_USE_COCOA */
{
Log (("Quartz2D: Creating\n"));
- resizeEvent (new VBoxResizeEvent (FramebufferPixelFormat_Opaque,
- NULL, 0, 0, 640, 480));
+
+#ifndef QT_MAC_USE_COCOA
+ /* There seems to be a big bug on Snow Leopard regarding hardware
+ * accelerated image handling in Carbon. If our VM image is used on a
+ * second monitor it seems not really to be valid. (maybe the OpenGL
+ * texture is not properly shared between the two contexts). As a
+ * workaround we make a deep copy on every paint event. This workaround
+ * should only be in place if we are firstly on Snow Leopard and secondly
+ * on any screen beside the primary one. To track the current screen, we
+ * install a event handler for the window move event. Whenever the user
+ * drag the window around we recheck the current screen of the window. */
+ char szInfo[64];
+ int rc = RTSystemQueryOSInfo (RTSYSOSINFO_RELEASE, szInfo, sizeof(szInfo));
+ if (RT_SUCCESS (rc) &&
+ szInfo[0] == '1') /* higher than 1x.x.x */
+ {
+ EventTypeSpec eventTypes[] =
+ {
+ { kEventClassWindow, kEventWindowBoundsChanged }
+ };
+ ::InstallWindowEventHandler (::darwinToNativeWindow (mView->viewport()), darwinSNWindowHandler, RT_ELEMENTS (eventTypes), &eventTypes[0],
+ this, &mDarwinSNWindowHandlerRef);
+ /* Initialize it now */
+ testAndSetSNCarbonFix();
+ }
+#endif /* QT_MAC_USE_COCOA */
+
+ VBoxResizeEvent event(FramebufferPixelFormat_Opaque,
+ NULL, 0, 0, 640, 480);
+ resizeEvent (&event);
}
VBoxQuartz2DFrameBuffer::~VBoxQuartz2DFrameBuffer()
{
Log (("Quartz2D: Deleting\n"));
clean();
+#ifndef QT_MAC_USE_COCOA
+ if (mDarwinSNWindowHandlerRef)
+ {
+ ::RemoveEventHandler (mDarwinSNWindowHandlerRef);
+ mDarwinSNWindowHandlerRef = NULL;
+ }
+#endif /* QT_MAC_USE_COCOA */
}
/** @note This method is called on EMT from under this object's lock */
@@ -178,12 +234,32 @@ void VBoxQuartz2DFrameBuffer::paintEvent (QPaintEvent *aEvent)
* Currently this subimage is the whole screen. */
CGImageRef subImage;
if (!mView->pauseShot().isNull())
- subImage = CGImageCreateWithImageInRect (::darwinToCGImageRef (&mView->pauseShot()), CGRectMake (mView->contentsX(), mView->contentsY(), mView->visibleWidth(), mView->visibleHeight()));
+ {
+ CGImageRef pauseImg = ::darwinToCGImageRef (&mView->pauseShot());
+ subImage = CGImageCreateWithImageInRect (pauseImg, CGRectMake (mView->contentsX(), mView->contentsY(), mView->visibleWidth(), mView->visibleHeight()));
+ CGImageRelease (pauseImg);
+ }
else
- subImage = CGImageCreateWithImageInRect (mImage, CGRectMake (mView->contentsX(), mView->contentsY(), mView->visibleWidth(), mView->visibleHeight()));
+ {
+
+#ifndef QT_MAC_USE_COCOA
+ /* For the reason of this see the constructor. */
+ if (mSnowLeoCarbonFix)
+ {
+ CGImageRef copy = CGImageCreateCopy (mImage);
+ subImage = CGImageCreateWithImageInRect (copy, CGRectMake (mView->contentsX(), mView->contentsY(), mView->visibleWidth(), mView->visibleHeight()));
+ CGImageRelease (copy);
+ }else
+#endif /* QT_MAC_USE_COCOA */
+ subImage = CGImageCreateWithImageInRect (mImage, CGRectMake (mView->contentsX(), mView->contentsY(), mView->visibleWidth(), mView->visibleHeight()));
+ }
Assert (VALID_PTR (subImage));
/* Clear the background (Make the rect fully transparent) */
CGContextClearRect (ctx, viewRect);
+#ifdef OVERLAY_CLIPRECTS
+ CGContextSetRGBFillColor (ctx, 0.0, 0.0, 5.0, 0.7);
+ CGContextFillRect (ctx, viewRect);
+#endif
#ifdef COMP_WITH_SHADOW
/* Enable shadows */
CGContextSetShadow (ctx, CGSizeMake (10, -10), 10);
@@ -214,6 +290,18 @@ void VBoxQuartz2DFrameBuffer::paintEvent (QPaintEvent *aEvent)
#ifdef COMP_WITH_SHADOW
CGContextEndTransparencyLayer (ctx);
#endif
+ CGImageRelease (subImage);
+#ifdef OVERLAY_CLIPRECTS
+ if (rgnRcts && rgnRcts->used > 0)
+ {
+ CGContextBeginPath (ctx);
+ CGContextAddRects (ctx, rgnRcts->rcts, rgnRcts->used);
+ CGContextSetRGBStrokeColor (ctx, 1.0, 0.0, 0.0, 0.7);
+ CGContextDrawPath (ctx, kCGPathStroke);
+ }
+ CGContextSetRGBStrokeColor (ctx, 0.0, 1.0, 0.0, 0.7);
+ CGContextStrokeRect (ctx, viewRect);
+#endif
}
else
{
@@ -225,9 +313,24 @@ void VBoxQuartz2DFrameBuffer::paintEvent (QPaintEvent *aEvent)
QRect is = QRect (ir.x() + mView->contentsX(), ir.y() + mView->contentsY(), ir.width(), ir.height());
CGImageRef subImage;
if (!mView->pauseShot().isNull())
- subImage = CGImageCreateWithImageInRect (::darwinToCGImageRef (&mView->pauseShot()), ::darwinToCGRect (is));
+ {
+ CGImageRef pauseImg = ::darwinToCGImageRef (&mView->pauseShot());
+ subImage = CGImageCreateWithImageInRect (pauseImg, ::darwinToCGRect (is));
+ CGImageRelease (pauseImg);
+ }
else
- subImage = CGImageCreateWithImageInRect (mImage, ::darwinToCGRect (is));
+ {
+#ifndef QT_MAC_USE_COCOA
+ /* For the reason of this see the constructor. */
+ if (mSnowLeoCarbonFix)
+ {
+ CGImageRef copy = CGImageCreateCopy (mImage);
+ subImage = CGImageCreateWithImageInRect (copy, ::darwinToCGRect (is));
+ CGImageRelease (copy);
+ }else
+#endif /* QT_MAC_USE_COCOA */
+ subImage = CGImageCreateWithImageInRect (mImage, ::darwinToCGRect (is));
+ }
Assert (VALID_PTR (subImage));
/* Ok, for more performance we set a clipping path of the
* regions given by this paint event. */
@@ -246,6 +349,8 @@ void VBoxQuartz2DFrameBuffer::paintEvent (QPaintEvent *aEvent)
CGContextClipToRect (ctx, viewRect);
/* At this point draw the real vm image */
CGContextDrawImage (ctx, ::darwinFlipCGRect (::darwinToCGRect (ir), viewRect.size.height), subImage);
+
+ CGImageRelease (subImage);
}
}
@@ -275,7 +380,6 @@ void VBoxQuartz2DFrameBuffer::resizeEvent (VBoxResizeEvent *aEvent)
&& aEvent->bitsPerPixel() == 32)
{
// printf ("VRAM\n");
- CGColorSpaceRef cs = CGColorSpaceCreateDeviceRGB();
/* Create the image copy of the framebuffer */
CGDataProviderRef dp = CGDataProviderCreateWithData (NULL, aEvent->VRAM(), aEvent->bitsPerPixel() / 8 * mWdt * mHgt, NULL);
mImage = CGImageCreate (mWdt, mHgt, 8, aEvent->bitsPerPixel(), aEvent->bytesPerLine(), cs,
@@ -348,4 +452,14 @@ void VBoxQuartz2DFrameBuffer::clean()
}
}
+#ifndef QT_MAC_USE_COCOA
+void VBoxQuartz2DFrameBuffer::testAndSetSNCarbonFix()
+{
+ QWidget* viewport = mView->viewport();
+ Assert (VALID_PTR (viewport));
+ QDesktopWidget dw;
+ mSnowLeoCarbonFix = dw.primaryScreen() != dw.screenNumber (viewport);
+}
+#endif /* QT_MAC_USE_COCOA */
+
#endif /* defined (VBOX_GUI_USE_QUARTZ2D) */
diff --git a/src/VBox/Frontends/VirtualBox/src/VBoxProblemReporter.cpp b/src/VBox/Frontends/VirtualBox/src/VBoxProblemReporter.cpp
index 0cc86fee7..4f13d8d35 100644
--- a/src/VBox/Frontends/VirtualBox/src/VBoxProblemReporter.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/VBoxProblemReporter.cpp
@@ -341,6 +341,32 @@ void VBoxProblemReporter::cannotDeleteFile (const QString& path, QWidget *aParen
.arg (path));
}
+void VBoxProblemReporter::checkForMountedWrongUSB() const
+{
+#ifdef RT_OS_LINUX
+ QFile file ("/proc/mounts");
+ if (file.exists() && file.open (QIODevice::ReadOnly | QIODevice::Text))
+ {
+ QStringList contents;
+ for (;;)
+ {
+ QByteArray line = file.readLine();
+ if (line.isEmpty())
+ break;
+ contents << line;
+ }
+ QStringList grep1 (contents.filter ("/sys/bus/usb/drivers"));
+ QStringList grep2 (grep1.filter ("usbfs"));
+ if (!grep2.isEmpty())
+ message (mainWindowShown(), Warning,
+ tr ("You seem to have the USBFS filesystem mounted at /sys/bus/usb/drivers. "
+ "We strongly recommend that you change this, as it is a severe mis-configuration of "
+ "your system which could cause USB devices to fail in unexpected ways."),
+ "checkForMountedWrongUSB");
+ }
+#endif
+}
+
// Special Problem handlers
/////////////////////////////////////////////////////////////////////////////
diff --git a/src/VBox/Frontends/VirtualBox/src/VBoxVMSettingsUSB.cpp b/src/VBox/Frontends/VirtualBox/src/VBoxVMSettingsUSB.cpp
index 607d21cd0..0872caa27 100644
--- a/src/VBox/Frontends/VirtualBox/src/VBoxVMSettingsUSB.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/VBoxVMSettingsUSB.cpp
@@ -37,6 +37,7 @@ inline static QString emptyToNull (const QString &str)
VBoxVMSettingsUSB::VBoxVMSettingsUSB (FilterType aType)
: mValidator (0)
, mType (aType)
+ , mUSBFilterListModified (false)
{
/* Apply UI decorations */
Ui::VBoxVMSettingsUSB::setupUi (this);
diff --git a/src/VBox/Frontends/VirtualBox/src/main.cpp b/src/VBox/Frontends/VirtualBox/src/main.cpp
index 2a101df88..72aa437ff 100644
--- a/src/VBox/Frontends/VirtualBox/src/main.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/main.cpp
@@ -471,6 +471,8 @@ extern "C" DECLEXPORT(int) TrustedMain (int argc, char **argv, char ** /*envp*/)
#endif
#endif
+ vboxProblem().checkForMountedWrongUSB();
+
VBoxGlobalSettings settings = vboxGlobal().settings();
/* Process known keys */
bool noSelector = settings.isFeatureActive ("noSelector");