Browse Source

Mac keyboard fix and camera tweak.

tags/2021-05-28
Julian Storer 15 years ago
parent
commit
8d05a9f2fa
5 changed files with 147 additions and 72 deletions
  1. +73
    -36
      juce_amalgamated.cpp
  2. +28
    -9
      src/native/mac/juce_mac_CameraDevice.mm
  3. +17
    -13
      src/native/mac/juce_mac_MainMenu.mm
  4. +11
    -1
      src/native/mac/juce_mac_NSViewComponentPeer.mm
  5. +18
    -13
      src/native/windows/juce_win32_CameraDevice.cpp

+ 73
- 36
juce_amalgamated.cpp View File

@@ -227589,19 +227589,24 @@ public:
}
}

imageSwapLock.enter();
const int lineStride = width * 3;
const Image::BitmapData destData (*loadingImage, 0, 0, width, height, true);
{
const int lineStride = width * 3;
const ScopedLock sl (imageSwapLock);

for (int i = 0; i < height; ++i)
memcpy (destData.getLinePointer ((height - 1) - i),
buffer + lineStride * i,
lineStride);
{
const Image::BitmapData destData (*loadingImage, 0, 0, width, height, true);

imageNeedsFlipping = true;
imageSwapLock.exit();
for (int i = 0; i < height; ++i)
memcpy (destData.getLinePointer ((height - 1) - i),
buffer + lineStride * i,
lineStride);
}

callListeners (*loadingImage);
imageNeedsFlipping = true;
}

if (listeners.size() > 0)
callListeners (*loadingImage);

sendChangeMessage (this);
}
@@ -227610,10 +227615,9 @@ public:
{
if (imageNeedsFlipping)
{
imageSwapLock.enter();
const ScopedLock sl (imageSwapLock);
swapVariables (loadingImage, activeImage);
imageNeedsFlipping = false;
imageSwapLock.exit();
}

RectanglePlacement rp (RectanglePlacement::centred);
@@ -227646,7 +227650,7 @@ public:

if (SUCCEEDED (hr))
{
fileWriter.CoCreateInstance (CLSID_FileWriter, CLSCTX_INPROC_SERVER);
hr = fileWriter.CoCreateInstance (CLSID_FileWriter, CLSCTX_INPROC_SERVER);

if (SUCCEEDED (hr))
{
@@ -245143,6 +245147,7 @@ END_JUCE_NAMESPACE
NSViewComponentPeer* owner;
NSNotificationCenter* notificationCenter;
String* stringBeingComposed;
bool textWasInserted;
}

- (JuceNSView*) initWithOwner: (NSViewComponentPeer*) owner withFrame: (NSRect) frame;
@@ -245359,6 +245364,7 @@ END_JUCE_NAMESPACE
[super initWithFrame: frame];
owner = owner_;
stringBeingComposed = 0;
textWasInserted = false;

notificationCenter = [NSNotificationCenter defaultCenter];

@@ -245522,13 +245528,14 @@ END_JUCE_NAMESPACE
- (void) keyDown: (NSEvent*) ev
{
TextInputTarget* const target = owner->findCurrentTextInputTarget();
textWasInserted = false;

if (target != 0)
[self interpretKeyEvents: [NSArray arrayWithObject: ev]];
else
deleteAndZero (stringBeingComposed);

if (stringBeingComposed == 0 && (owner == 0 || ! owner->redirectKeyDown (ev)))
if ((! textWasInserted) && (owner == 0 || ! owner->redirectKeyDown (ev)))
[super keyDown: ev];
}

@@ -245546,7 +245553,10 @@ END_JUCE_NAMESPACE
TextInputTarget* const target = owner->findCurrentTextInputTarget();

if (target != 0)
{
target->insertTextAtCaret (nsStringToJuce ([aString isKindOfClass: [NSAttributedString class]] ? [aString string] : aString));
textWasInserted = true;
}
}

deleteAndZero (stringBeingComposed);
@@ -245570,6 +245580,7 @@ END_JUCE_NAMESPACE
const Range<int> currentHighlight (target->getHighlightedRegion());
target->insertTextAtCaret (*stringBeingComposed);
target->setHighlightedRegion (currentHighlight.withLength (stringBeingComposed->length()));
textWasInserted = true;
}
}

@@ -245580,7 +245591,10 @@ END_JUCE_NAMESPACE
TextInputTarget* const target = owner->findCurrentTextInputTarget();

if (target != 0)
{
target->insertTextAtCaret (*stringBeingComposed);
textWasInserted = true;
}
}

deleteAndZero (stringBeingComposed);
@@ -247726,6 +247740,9 @@ public:

static void flashMenuBar (NSMenu* menu)
{
if ([[menu title] isEqualToString: @"Apple"])
return;

[menu retain];

const unichar f35Key = NSF35FunctionKey;
@@ -247738,21 +247755,22 @@ public:
[menu insertItem: item atIndex: [menu numberOfItems]];
[item release];

NSEvent* f35Event = [NSEvent keyEventWithType: NSKeyDown
location: NSZeroPoint
modifierFlags: NSCommandKeyMask
timestamp: 0
windowNumber: 0
context: [NSGraphicsContext currentContext]
characters: f35String
charactersIgnoringModifiers: f35String
isARepeat: NO
keyCode: 0];

[menu performKeyEquivalent: f35Event];

if ([menu indexOfItem: item] >= 0)
{
NSEvent* f35Event = [NSEvent keyEventWithType: NSKeyDown
location: NSZeroPoint
modifierFlags: NSCommandKeyMask
timestamp: 0
windowNumber: 0
context: [NSGraphicsContext currentContext]
characters: f35String
charactersIgnoringModifiers: f35String
isARepeat: NO
keyCode: 0];

[menu performKeyEquivalent: f35Event];
[menu removeItem: item]; // (this throws if the item isn't actually in the menu)
}

[menu release];
}
@@ -251841,7 +251859,8 @@ END_JUCE_NAMESPACE
@public
CameraDevice* owner;
QTCameraDeviceInteral* internal;
Time* firstRecordedTime;
int64 firstPresentationTime;
int64 averageTimeOffset;
}

- (QTCaptureCallbackDelegate*) initWithOwner: (CameraDevice*) owner internalDev: (QTCameraDeviceInteral*) d;
@@ -252016,13 +252035,13 @@ END_JUCE_NAMESPACE
[super init];
owner = owner_;
internal = d;
firstRecordedTime = 0;
firstPresentationTime = 0;
averageTimeOffset = 0;
return self;
}

- (void) dealloc
{
delete firstRecordedTime;
[super dealloc];
}

@@ -252045,10 +252064,28 @@ END_JUCE_NAMESPACE
didOutputSampleBuffer: (QTSampleBuffer*) sampleBuffer
fromConnection: (QTCaptureConnection*) connection
{
if (firstRecordedTime == 0)
const Time now (Time::getCurrentTime());
int64 presentationTime = ([sampleBuffer presentationTime].timeValue * 1000) / [sampleBuffer presentationTime].timeScale;

#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
NSNumber* hosttime = (NSNumber*) [sampleBuffer attributeForKey: QTSampleBufferHostTimeAttribute];
#else
NSNumber* hosttime = (NSNumber*) [sampleBuffer attributeForKey: @"hostTime"];
#endif

if (hosttime != nil)
presentationTime = (int64) AudioConvertHostTimeToNanos ([hosttime unsignedLongLongValue]) / 1000000;

const int64 timeDiff = now.toMilliseconds() - presentationTime - 50;

if (firstPresentationTime == 0)
{
firstPresentationTime = presentationTime;
averageTimeOffset = timeDiff;
}
else
{
const Time now (Time::getCurrentTime());
firstRecordedTime = new Time (now - RelativeTime (0.1));
averageTimeOffset = (averageTimeOffset * 120 + timeDiff * 8) / 128;
}
}

@@ -252108,7 +252145,7 @@ void CameraDevice::startRecordingToFile (const File& file, int quality)
stopRecording();

QTCameraDeviceInteral* const d = (QTCameraDeviceInteral*) internal;
deleteAndZero (d->callbackDelegate->firstRecordedTime);
d->callbackDelegate->firstPresentationTime = 0;
file.deleteFile();

// In some versions of QT (e.g. on 10.5), if you record video without audio, the speed comes
@@ -252145,8 +252182,8 @@ void CameraDevice::startRecordingToFile (const File& file, int quality)
const Time CameraDevice::getTimeOfFirstRecordedFrame() const
{
QTCameraDeviceInteral* const d = (QTCameraDeviceInteral*) internal;
if (d->callbackDelegate->firstRecordedTime != 0)
return *d->callbackDelegate->firstRecordedTime;
if (d->callbackDelegate->firstPresentationTime != 0)
return Time (d->callbackDelegate->firstPresentationTime + d->callbackDelegate->averageTimeOffset);

return Time();
}


+ 28
- 9
src/native/mac/juce_mac_CameraDevice.mm View File

@@ -39,7 +39,8 @@ END_JUCE_NAMESPACE
@public
CameraDevice* owner;
QTCameraDeviceInteral* internal;
Time* firstRecordedTime;
int64 firstPresentationTime;
int64 averageTimeOffset;
}
- (QTCaptureCallbackDelegate*) initWithOwner: (CameraDevice*) owner internalDev: (QTCameraDeviceInteral*) d;
@@ -215,13 +216,13 @@ END_JUCE_NAMESPACE
[super init];
owner = owner_;
internal = d;
firstRecordedTime = 0;
firstPresentationTime = 0;
averageTimeOffset = 0;
return self;
}
- (void) dealloc
{
delete firstRecordedTime;
[super dealloc];
}
@@ -244,10 +245,28 @@ END_JUCE_NAMESPACE
didOutputSampleBuffer: (QTSampleBuffer*) sampleBuffer
fromConnection: (QTCaptureConnection*) connection
{
if (firstRecordedTime == 0)
const Time now (Time::getCurrentTime());
int64 presentationTime = ([sampleBuffer presentationTime].timeValue * 1000) / [sampleBuffer presentationTime].timeScale;
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
NSNumber* hosttime = (NSNumber*) [sampleBuffer attributeForKey: QTSampleBufferHostTimeAttribute];
#else
NSNumber* hosttime = (NSNumber*) [sampleBuffer attributeForKey: @"hostTime"];
#endif
if (hosttime != nil)
presentationTime = (int64) AudioConvertHostTimeToNanos ([hosttime unsignedLongLongValue]) / 1000000;
const int64 timeDiff = now.toMilliseconds() - presentationTime - 50;
if (firstPresentationTime == 0)
{
firstPresentationTime = presentationTime;
averageTimeOffset = timeDiff;
}
else
{
const Time now (Time::getCurrentTime());
firstRecordedTime = new Time (now - RelativeTime (0.1));
averageTimeOffset = (averageTimeOffset * 120 + timeDiff * 8) / 128;
}
}
@@ -309,7 +328,7 @@ void CameraDevice::startRecordingToFile (const File& file, int quality)
stopRecording();
QTCameraDeviceInteral* const d = (QTCameraDeviceInteral*) internal;
deleteAndZero (d->callbackDelegate->firstRecordedTime);
d->callbackDelegate->firstPresentationTime = 0;
file.deleteFile();
// In some versions of QT (e.g. on 10.5), if you record video without audio, the speed comes
@@ -346,8 +365,8 @@ void CameraDevice::startRecordingToFile (const File& file, int quality)
const Time CameraDevice::getTimeOfFirstRecordedFrame() const
{
QTCameraDeviceInteral* const d = (QTCameraDeviceInteral*) internal;
if (d->callbackDelegate->firstRecordedTime != 0)
return *d->callbackDelegate->firstRecordedTime;
if (d->callbackDelegate->firstPresentationTime != 0)
return Time (d->callbackDelegate->firstPresentationTime + d->callbackDelegate->averageTimeOffset);
return Time();
}


+ 17
- 13
src/native/mac/juce_mac_MainMenu.mm View File

@@ -155,6 +155,9 @@ public:
static void flashMenuBar (NSMenu* menu)
{
if ([[menu title] isEqualToString: @"Apple"])
return;
[menu retain];
const unichar f35Key = NSF35FunctionKey;
@@ -167,21 +170,22 @@ public:
[menu insertItem: item atIndex: [menu numberOfItems]];
[item release];
NSEvent* f35Event = [NSEvent keyEventWithType: NSKeyDown
location: NSZeroPoint
modifierFlags: NSCommandKeyMask
timestamp: 0
windowNumber: 0
context: [NSGraphicsContext currentContext]
characters: f35String
charactersIgnoringModifiers: f35String
isARepeat: NO
keyCode: 0];
[menu performKeyEquivalent: f35Event];
if ([menu indexOfItem: item] >= 0)
{
NSEvent* f35Event = [NSEvent keyEventWithType: NSKeyDown
location: NSZeroPoint
modifierFlags: NSCommandKeyMask
timestamp: 0
windowNumber: 0
context: [NSGraphicsContext currentContext]
characters: f35String
charactersIgnoringModifiers: f35String
isARepeat: NO
keyCode: 0];
[menu performKeyEquivalent: f35Event];
[menu removeItem: item]; // (this throws if the item isn't actually in the menu)
}
[menu release];
}


+ 11
- 1
src/native/mac/juce_mac_NSViewComponentPeer.mm View File

@@ -40,6 +40,7 @@ END_JUCE_NAMESPACE
NSViewComponentPeer* owner;
NSNotificationCenter* notificationCenter;
String* stringBeingComposed;
bool textWasInserted;
}
- (JuceNSView*) initWithOwner: (NSViewComponentPeer*) owner withFrame: (NSRect) frame;
@@ -273,6 +274,7 @@ END_JUCE_NAMESPACE
[super initWithFrame: frame];
owner = owner_;
stringBeingComposed = 0;
textWasInserted = false;
notificationCenter = [NSNotificationCenter defaultCenter];
@@ -439,13 +441,14 @@ END_JUCE_NAMESPACE
- (void) keyDown: (NSEvent*) ev
{
TextInputTarget* const target = owner->findCurrentTextInputTarget();
textWasInserted = false;
if (target != 0)
[self interpretKeyEvents: [NSArray arrayWithObject: ev]];
else
deleteAndZero (stringBeingComposed);
if (stringBeingComposed == 0 && (owner == 0 || ! owner->redirectKeyDown (ev)))
if ((! textWasInserted) && (owner == 0 || ! owner->redirectKeyDown (ev)))
[super keyDown: ev];
}
@@ -464,7 +467,10 @@ END_JUCE_NAMESPACE
TextInputTarget* const target = owner->findCurrentTextInputTarget();
if (target != 0)
{
target->insertTextAtCaret (nsStringToJuce ([aString isKindOfClass: [NSAttributedString class]] ? [aString string] : aString));
textWasInserted = true;
}
}
deleteAndZero (stringBeingComposed);
@@ -488,6 +494,7 @@ END_JUCE_NAMESPACE
const Range<int> currentHighlight (target->getHighlightedRegion());
target->insertTextAtCaret (*stringBeingComposed);
target->setHighlightedRegion (currentHighlight.withLength (stringBeingComposed->length()));
textWasInserted = true;
}
}
@@ -498,7 +505,10 @@ END_JUCE_NAMESPACE
TextInputTarget* const target = owner->findCurrentTextInputTarget();
if (target != 0)
{
target->insertTextAtCaret (*stringBeingComposed);
textWasInserted = true;
}
}
deleteAndZero (stringBeingComposed);


+ 18
- 13
src/native/windows/juce_win32_CameraDevice.cpp View File

@@ -210,19 +210,24 @@ public:
}
}
imageSwapLock.enter();
const int lineStride = width * 3;
const Image::BitmapData destData (*loadingImage, 0, 0, width, height, true);
{
const int lineStride = width * 3;
const ScopedLock sl (imageSwapLock);
{
const Image::BitmapData destData (*loadingImage, 0, 0, width, height, true);
for (int i = 0; i < height; ++i)
memcpy (destData.getLinePointer ((height - 1) - i),
buffer + lineStride * i,
lineStride);
for (int i = 0; i < height; ++i)
memcpy (destData.getLinePointer ((height - 1) - i),
buffer + lineStride * i,
lineStride);
}
imageNeedsFlipping = true;
imageSwapLock.exit();
imageNeedsFlipping = true;
}
callListeners (*loadingImage);
if (listeners.size() > 0)
callListeners (*loadingImage);
sendChangeMessage (this);
}
@@ -231,10 +236,9 @@ public:
{
if (imageNeedsFlipping)
{
imageSwapLock.enter();
const ScopedLock sl (imageSwapLock);
swapVariables (loadingImage, activeImage);
imageNeedsFlipping = false;
imageSwapLock.exit();
}
RectanglePlacement rp (RectanglePlacement::centred);
@@ -267,7 +271,7 @@ public:
if (SUCCEEDED (hr))
{
fileWriter.CoCreateInstance (CLSID_FileWriter, CLSCTX_INPROC_SERVER);
hr = fileWriter.CoCreateInstance (CLSID_FileWriter, CLSCTX_INPROC_SERVER);
if (SUCCEEDED (hr))
{
@@ -378,6 +382,7 @@ public:
}
}
//==============================================================================
class DShowCaptureViewerComp : public Component,
public ChangeListener


Loading…
Cancel
Save