[vlc-devel] [PATCH v2] Dim MacBook keyboard backlight during video playback on OSX
David Fuhrmann
david.fuhrmann at gmail.com
Tue May 19 21:09:17 CEST 2015
Hi,
> Am 18.05.2015 um 22:36 schrieb Maxime Mouchet <max at maxmouchet.com>:
>
> This patch adds the option to 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.
>
> Smooth brightness transitions are implemented, and the "before-playing"
> level is saved to be restored on pause.
> If the user manually (i.e. using hardware keys) put backlight on,
> brightness level is not changed, in order to preserve his choice.
> ---
> This edited version gets rid of the singleton and moves the code concerning
> fullscreen transitions in VLCVoutWindowController.
Well, getting rid of the singleton only makes sense if we can integrate your class in one place only - my idea was to do it in VLCVoutController as you should have all events here.
> I kept the code to manage play an pause transitions in VLCIntf (in the same
> place as the code for iTunes and Spotify).
Why?
> It should also close the dataPort correctly.
>
> To sum up, the expected behavior is:
> * Dim backlight when a video is playing and entering fullscreen (in VLCVoutWindowController).
> * Dim backlight when starting video playback in fullscreen (in intf).
This should be possible to do in VoutWindowController as well: When video playback is started, setupVoutForWindow:… is called.
> * Restore backlight when exiting fullscreen (in VLCVoutWindowController).
> * Restore backlight on pause/stop,
You want to restore the blacklight on pause as well? Why?
> or when exiting (in intf).
Isn’t it possible to do that in VoutWindowController as well? But its good that you think about termination as well - we should have no extra thread running why the main loop already quit.
>
> 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 | 12 +-
> modules/gui/macosx/intf.h | 3 +
> modules/gui/macosx/intf.m | 19 ++++
> modules/gui/macosx/macosx.m | 4 +
> 8 files changed, 268 insertions(+), 1 deletion(-)
> 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..5cc235d 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,7 @@
> for (NSValue *key in keys)
> [self removeVoutforDisplay:key];
>
> + [o_keyboard_backlight release];
> [o_vout_dict release];
> [super dealloc];
> }
> @@ -339,6 +341,15 @@
> if(p_wnd)
> o_current_window = [o_vout_dict objectForKey:[NSValue valueWithPointer:p_wnd]];
>
> + input_thread_t * p_input = pl_CurrentInput(p_intf);
> +
> + // Disable keyboard backlight when entering fullscreen and a video is playing.
> + // Restore keyboard backlight when exiting fullscreen.
> + if (p_input != NULL && var_InheritBool(p_intf, "macosx-dim-keyboard")) {
> + BOOL b_backlight_off = (b_fullscreen && var_GetInteger(p_input, "state") == PLAYING_S);
> + [o_keyboard_backlight switchLightsAsync:!b_backlight_off];
> + }
Why checking for input and PLAYING_S here? Should not be necessary I think.
> +
> if (b_nativeFullscreenMode) {
> if(!o_current_window)
> o_current_window = [VLCMainWindow sharedInstance];
> @@ -355,7 +366,6 @@
> assert(o_current_window);
>
> if (b_fullscreen) {
> - input_thread_t * p_input = pl_CurrentInput(p_intf);
> if (p_input != NULL && [[VLCMain sharedInstance] activeVideoPlayback]) {
> // activate app, as method can also be triggered from outside the app (prevents nasty window layout)
> [NSApp activateIgnoringOtherApps:YES];
> diff --git a/modules/gui/macosx/intf.h b/modules/gui/macosx/intf.h
> index bbb5283..c46ac37 100644
> --- a/modules/gui/macosx/intf.h
> +++ b/modules/gui/macosx/intf.h
> @@ -43,6 +43,7 @@
> #import "MainWindow.h"
> #import "VLCVoutWindowController.h"
> #import "StringUtility.h"
> +#import "KeyboardBacklight.h"
>
> #import <IOKit/pwr_mgt/IOPMLib.h> /* for sleep prevention */
>
> @@ -120,6 +121,8 @@ static NSString * VLCInputChangedNotification = @"VLCInputChangedNotification";
> BOOL b_has_spotify_paused;
> NSTimer *o_itunes_play_timer;
>
> + KeyboardBacklight *o_keyboard_backlight;
> +
> dispatch_queue_t informInputChangedQueue;
> }
>
> diff --git a/modules/gui/macosx/intf.m b/modules/gui/macosx/intf.m
> index 678952b..d3071a7 100644
> --- a/modules/gui/macosx/intf.m
> +++ b/modules/gui/macosx/intf.m
> @@ -672,6 +672,7 @@ static VLCMain *_o_sharedMainInstance = nil;
> o_mainmenu = [[VLCMainMenu alloc] init];
> o_coreinteraction = [[VLCCoreInteraction alloc] init];
> o_eyetv = [[VLCEyeTVController alloc] init];
> + o_keyboard_backlight = [[KeyboardBacklight alloc] init];
>
> /* announce our launch to a potential eyetv plugin */
> [[NSDistributedNotificationCenter defaultCenter] postNotificationName: @"VLCOSXGUIInit"
> @@ -876,6 +877,11 @@ static bool f_appExit = false;
>
> [self resumeItunesPlayback:nil];
>
> + /* Restore keyboard backlight when exiting */
> + if (var_InheritBool(p_intf, "macosx-dim-keyboard")) {
> + [o_keyboard_backlight switchLightsInstantly:YES];
> + }
> +
> if (notification == nil)
> [[NSNotificationCenter defaultCenter] postNotificationName: NSApplicationWillTerminateNotification object: nil];
>
> @@ -953,6 +959,7 @@ static bool f_appExit = false;
> [o_coredialogs release];
> [o_eyetv release];
> [o_remote release];
> + [o_keyboard_backlight release];
>
> /* unsubscribe from libvlc's debug messages */
> vlc_LogSet(p_intf->p_libvlc, NULL, NULL);
> @@ -1539,6 +1546,8 @@ static bool f_appExit = false;
> }
> }
>
> + BOOL b_backlight_on = YES;
> +
> if (state == PLAYING_S) {
> if (i_control_itunes > 0) {
> // pause iTunes
> @@ -1569,6 +1578,9 @@ static bool f_appExit = false;
> }
> }
>
> + /* Dim keyboard backlight if a video is playing in fullscreen */
> + b_backlight_on = !(var_InheritBool(p_intf, "fullscreen") && [self activeVideoPlayback]);
> +
> /* Declare user activity.
> This wakes the display if it is off, and postpones display sleep according to the users system preferences
> Available from 10.7.3 */
> @@ -1618,6 +1630,9 @@ static bool f_appExit = false;
> [[self mainMenu] setPlay];
> [o_mainwindow setPlay];
>
> + /* Restore keyboard backlight when nothing is playing */
> + b_backlight_on = YES;
> +
> /* allow the system to sleep again */
> if (systemSleepAssertionID > 0) {
> msg_Dbg(VLCIntf, "releasing sleep blocker (%i)" , systemSleepAssertionID);
> @@ -1642,6 +1657,10 @@ static bool f_appExit = false;
> }
> }
>
> + if (var_InheritBool(p_intf, "macosx-dim-keyboard")) {
> + [o_keyboard_backlight switchLightsAsync:b_backlight_on];
> + }
> +
> [[VLCMain sharedInstance] performSelectorOnMainThread:@selector(updateMainWindow) withObject: nil waitUntilDone: NO];
> [self performSelectorOnMainThread:@selector(sendDistributedNotificationWithUpdatedPlaybackStatus) withObject: nil waitUntilDone: NO];
> }
> diff --git a/modules/gui/macosx/macosx.m b/modules/gui/macosx/macosx.m
> index 1c73e96..e1d84ef 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 keyboad 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
Best regards,
David
More information about the vlc-devel
mailing list