[vlc-devel] [PATCH v3] Dim MacBook keyboard backlight during video playback on OSX
David Fuhrmann
david.fuhrmann at gmail.com
Sat May 30 13:44:03 CEST 2015
Hello Maxime,
> Am 28.05.2015 um 20:24 schrieb Maxime Mouchet <max at maxmouchet.com>:
>
> This patch adds the option to smoothly turn off the keyboard backlight when
> a video is playing in fullscreen, to the OSX user interface.
> The option is off by default and it works better if the automatic
> keyboard backlight adjustment is disabled in System Preferences.
> ---
> Hi,
>
> This is the edited patch following the suggestions from the previous versions.
> Logic is now implemented only in VoutWindowController and behaves as follow:
> * Dim keyboard backlight when entering fullscreen.
> * Restore backlight when exiting fullscreen or when quitting VLC.
>
> I hope it looks better :-)
>
> Regards,
>
> modules/gui/macosx/KeyboardBacklight.h | 68 ++++++++++++
> modules/gui/macosx/KeyboardBacklight.m | 158 +++++++++++++++++++++++++++
> modules/gui/macosx/Modules.am | 3 +
> modules/gui/macosx/VLCVoutWindowController.h | 2 +
> modules/gui/macosx/VLCVoutWindowController.m | 10 ++
> modules/gui/macosx/macosx.m | 4 +
> 6 files changed, 245 insertions(+)
> create mode 100644 modules/gui/macosx/KeyboardBacklight.h
> create mode 100644 modules/gui/macosx/KeyboardBacklight.m
>
> diff --git a/modules/gui/macosx/KeyboardBacklight.h b/modules/gui/macosx/KeyboardBacklight.h
> new file mode 100644
> index 0000000..306ecf3
> --- /dev/null
> +++ b/modules/gui/macosx/KeyboardBacklight.h
> @@ -0,0 +1,68 @@
> +/*****************************************************************************
> + * KeyboardBacklight.h: MacBook keyboard backlight control for VLC
> + *****************************************************************************
> + * Copyright (C) 2015 VLC authors and VideoLAN
> + *
> + *
> + * Authors: Maxime Mouchet <max at maxmouchet.com>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
> + *****************************************************************************/
> +
> +#import <Foundation/Foundation.h>
> +#import <IOKit/IOKitLib.h>
> +
> +enum {
> + kGetSensorReadingID = 0, // getSensorReading(int *, int *)
> + kGetLEDBrightnessID = 1, // getLEDBrightness(int, int *)
> + kSetLEDBrightnessID = 2, // setLEDBrightness(int, int, int *)
> + kSetLEDFadeID = 3 // setLEDFade(int, int, int, int *)
> +};
> +
> + at interface KeyboardBacklight : NSObject
> +
> +/*!
> + * Initialize an instance of KeyboardBacklight.
> + *
> + * Note: this will return nil if the connection to
> + * the controller could not be opened.
> + */
> +- (id)init;
> +
> +/*!
> + * Smoothly turn on backlight on MacBook keyboard.
> + *
> + * Try to restore the previous brightness level. If the user has put
> + * the backlight on manually (using hardware keys), nothing will be done.
> + */
> +- (void)lightsUp;
> +
> +/*!
> + * Smoothly turn off backlight on MacBook keyboard.
> + */
> +- (void)lightsDown;
> +
> +/*!
> + * Smoothly switch on or off backlight on MacBook keyboard.
> + * This will return immediately.
> + */
> +- (void)switchLightsAsync:(BOOL)on;
> +
> +/*!
> + * Instantly switch on or off backlight on MacBook keyboard.
> + */
> +- (void)switchLightsInstantly:(BOOL)on;
> +
> + at end
> diff --git a/modules/gui/macosx/KeyboardBacklight.m b/modules/gui/macosx/KeyboardBacklight.m
> new file mode 100644
> index 0000000..e747f9d
> --- /dev/null
> +++ b/modules/gui/macosx/KeyboardBacklight.m
> @@ -0,0 +1,158 @@
> +/*****************************************************************************
> + * KeyboardBacklight.m: MacBook keyboard backlight control for VLC
> + *****************************************************************************
> + * Copyright (C) 2015 VLC authors and VideoLAN
> + *
> + *
> + * Authors: Maxime Mouchet <max at maxmouchet.com>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
> + *****************************************************************************/
> +
> +#import "KeyboardBacklight.h"
> +
> + at implementation KeyboardBacklight {
> + io_connect_t dataPort;
> +}
> +
> +static float lastBrightnessLevel;
> +
> +- (id)init {
> + dataPort = [self getDataPort];
> + lastBrightnessLevel = [self getBrightness];
> + return self;
> +}
> +
> +- (void)dealloc {
> + if (dataPort) { IOServiceClose(dataPort); }
> + [super dealloc];
> +}
> +
> +- (io_connect_t)getDataPort {
> + if (dataPort) return dataPort;
> +
> + io_service_t serviceObject = IOServiceGetMatchingService(kIOMasterPortDefault, IOServiceMatching("AppleLMUController"));
> +
> + if (!serviceObject) return 0;
> +
> + kern_return_t kr = IOServiceOpen(serviceObject, mach_task_self(), 0, &dataPort);
> + IOObjectRelease(serviceObject);
> +
> + if (kr != KERN_SUCCESS) return 0;
> +
> + return dataPort;
> +}
> +
> +- (void)setBrightness:(float)brightness {
> + if (!dataPort) return;
> +
> + UInt32 inputCount = 2;
> + UInt64 inputValues[2] = { 0, brightness * 0xfff };
> +
> + UInt32 outputCount = 1;
> + UInt64 outputValues[1];
> +
> + kern_return_t kr = IOConnectCallScalarMethod(dataPort,
> + kSetLEDBrightnessID,
> + inputValues,
> + inputCount,
> + outputValues,
> + &outputCount);
> +
> + if (kr != KERN_SUCCESS) return;
> +}
> +
> +- (float)getBrightness {
> + if (!dataPort) return 0.0;
> +
> + uint32_t inputCount = 1;
> + uint64_t inputValues[1] = { 0 };
> +
> + uint32_t outputCount = 1;
> + uint64_t outputValues[1];
> +
> + kern_return_t kr = IOConnectCallScalarMethod(dataPort,
> + kGetLEDBrightnessID,
> + inputValues,
> + inputCount,
> + outputValues,
> + &outputCount);
> +
> + float brightness = -1.0;
> + if (kr == KERN_SUCCESS) {
> + brightness = (float)outputValues[0] / 0xfff;
> + }
> +
> + return brightness;
> +}
> +
> +- (void)lightsUp {
> + if (!dataPort) return;
> +
> + @synchronized(self) {
> + float start = [self getBrightness];
> + float target = lastBrightnessLevel;
> +
> + // Don't do anything if the user has put
> + // backlight on again during playback.
> + if (start != 0) return;
> +
> + for (float i = start; i <= target; i += 0.08) {
> + [self setBrightness:i];
> + [NSThread sleepForTimeInterval:0.05];
> + }
> +
> + [self setBrightness:target];
> + }
> +}
> +
> +- (void)lightsDown {
> + if (!dataPort) return;
> +
> + @synchronized(self) {
> + float start = [self getBrightness];
> + float target = 0;
> +
> + lastBrightnessLevel = start;
> +
> + for (float i = start; i >= target; i -= 0.08) {
> + [self setBrightness:i];
> + [NSThread sleepForTimeInterval:0.05];
> + }
> +
> + [self setBrightness:target];
> + }
> +}
> +
> +- (void)switchLightsAsync:(BOOL)on {
> + if (on) {
> + [NSThread detachNewThreadSelector:@selector(lightsUp) toTarget:self withObject:nil];
> + } else {
> + [NSThread detachNewThreadSelector:@selector(lightsDown) toTarget:self withObject:nil];
> + }
> +}
> +
> +- (void)switchLightsInstantly:(BOOL)on {
> + if (on) {
> + // Don't do anything if the user has put backlight on again during playback.
> + if ([self getBrightness] == 0) {
> + [self setBrightness:lastBrightnessLevel];
> + }
> + } else {
> + [self setBrightness:0];
> + }
> +}
> +
> + at end
> diff --git a/modules/gui/macosx/Modules.am b/modules/gui/macosx/Modules.am
> index c796624..efd8625 100644
> --- a/modules/gui/macosx/Modules.am
> +++ b/modules/gui/macosx/Modules.am
> @@ -1,4 +1,5 @@
> AM_LIBTOOLFLAGS=--tag=CC
> +AM_LDFLAGS=-framework IOKit
>
> SOURCES_macosx = \
> CompatibilityFixes.h \
> @@ -99,4 +100,6 @@ SOURCES_macosx = \
> PLItem.m \
> PLModel.h \
> PLModel.m \
> + KeyboardBacklight.h \
> + KeyboardBacklight.m
> $(NULL)
> diff --git a/modules/gui/macosx/VLCVoutWindowController.h b/modules/gui/macosx/VLCVoutWindowController.h
> index c6a61dd..9c2164f 100644
> --- a/modules/gui/macosx/VLCVoutWindowController.h
> +++ b/modules/gui/macosx/VLCVoutWindowController.h
> @@ -25,6 +25,7 @@
> #import <Cocoa/Cocoa.h>
>
> #import <vlc_vout_window.h>
> +#import "KeyboardBacklight.h"
>
> @class VLCVideoWindowCommon;
> @class VLCVoutView;
> @@ -32,6 +33,7 @@
> @interface VLCVoutWindowController : NSObject
> {
> NSMutableDictionary *o_vout_dict;
> + KeyboardBacklight *o_keyboard_backlight;
>
> NSPoint top_left_point;
>
> diff --git a/modules/gui/macosx/VLCVoutWindowController.m b/modules/gui/macosx/VLCVoutWindowController.m
> index 53ed3fe..38c80d3 100644
> --- a/modules/gui/macosx/VLCVoutWindowController.m
> +++ b/modules/gui/macosx/VLCVoutWindowController.m
> @@ -40,6 +40,7 @@
> {
> self = [super init];
> o_vout_dict = [[NSMutableDictionary alloc] init];
> + o_keyboard_backlight = [[KeyboardBacklight alloc] init];
> i_currentWindowLevel = NSNormalWindowLevel;
> i_currentFloatingWindowLevel = NSFloatingWindowLevel;
> return self;
> @@ -51,6 +52,11 @@
> for (NSValue *key in keys)
> [self removeVoutforDisplay:key];
>
> + if (var_InheritBool(VLCIntf, "macosx-dim-keyboard")) {
> + [o_keyboard_backlight switchLightsInstantly:YES];
> + }
> +
> + [o_keyboard_backlight release];
> [o_vout_dict release];
> [super dealloc];
> }
> @@ -339,6 +345,10 @@
> if(p_wnd)
> o_current_window = [o_vout_dict objectForKey:[NSValue valueWithPointer:p_wnd]];
>
> + if (var_InheritBool(p_intf, "macosx-dim-keyboard")) {
> + [o_keyboard_backlight switchLightsAsync:!b_fullscreen];
> + }
> +
> if (b_nativeFullscreenMode) {
> if(!o_current_window)
> o_current_window = [VLCMainWindow sharedInstance];
> diff --git a/modules/gui/macosx/macosx.m b/modules/gui/macosx/macosx.m
> index 1c73e96..37092c8 100644
> --- a/modules/gui/macosx/macosx.m
> +++ b/modules/gui/macosx/macosx.m
> @@ -107,6 +107,9 @@ void WindowClose (vout_window_t *);
>
> #define LOCK_ASPECT_RATIO_TEXT N_("Lock Aspect Ratio")
>
> +#define DIM_KEYBOARD_PLAYBACK_TEXT N_("Dim keyboard backlight during fullscreen playback")
> +#define DIM_KEYBOARD_PLAYBACK_LONGTEXT N_("Turn off the MacBook keyboard backlight while a video is playing in fullscreen. Automatic brightness adjustment should be disabled in System Preferences.")
> +
> #define JUMPBUTTONS_TEXT N_("Show Previous & Next Buttons")
> #define JUMPBUTTONS_LONGTEXT N_("Shows the previous and next buttons in the main window.")
>
> @@ -168,6 +171,7 @@ vlc_module_begin()
> add_bool("macosx-video-autoresize", true, KEEPSIZE_TEXT, KEEPSIZE_LONGTEXT, false)
> add_bool("macosx-pause-minimized", false, PAUSE_MINIMIZED_TEXT, PAUSE_MINIMIZED_LONGTEXT, false)
> add_bool("macosx-lock-aspect-ratio", true, LOCK_ASPECT_RATIO_TEXT, LOCK_ASPECT_RATIO_TEXT, true)
> + add_bool("macosx-dim-keyboard", false, DIM_KEYBOARD_PLAYBACK_TEXT, DIM_KEYBOARD_PLAYBACK_LONGTEXT, false)
> add_integer("macosx-control-itunes", 1, ITUNES_TEXT, ITUNES_LONGTEXT, false)
> change_integer_list(itunes_list, itunes_list_text)
> add_integer("macosx-continue-playback", 0, CONTINUE_PLAYBACK_TEXT, CONTINUE_PLAYBACK_LONGTEXT, false)
> --
> 2.4.0
Thanks for the revised patch, I merged it for now.
But we found one issue we would like to ask you to fix if possible: Its not good to simply fire threads to change the blacklights. If you try switching fullscreen quickly (just quickly press cmd+f a couple of times), you see the lights repeatedly flashing a couple of seconds even after the animation has been finished.
We should cancel previous threads before firing a new one. Speaking of that, maybe it makes even sense to get rid of the threads altogether and switch to a timer doing the animation? I assume the system call is fast enough to be executed on the main thread, and you can easily cancel the timer if a new request comes in.
Best regards,
David
More information about the vlc-devel
mailing list