diff options
Diffstat (limited to 'src/VBox/Frontends/VirtualBox/src')
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"); |