[vlc-devel] [PATCH] Dim MacBook keyboard backlight during video playback on OSX

David Fuhrmann david.fuhrmann at gmail.com
Mon May 11 22:41:47 CEST 2015


Hi Maxime,

Thanks for the updated patch. Some small additional comments from me.

> Am 11.05.2015 um 19:01 schrieb Maxime Mouchet <max at maxmouchet.com>:
> 
> Hello,
> 
> Here is the edited patch including the code fixes and the new behavior. Keyboard backlight is now turned off only during fullscreen playback. Lights will be dimmed when fullscreen is entered while a video is playing, and restored when fullscreen is exited.
> 
> Regards,
> Maxime
> 
> 
> 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.
>
In the next patch, please add additional text for the mail here (after ---). Then, it does not get included in the final commit. :-)

> modules/gui/macosx/CoreInteraction.m   |  23 +++++-
> modules/gui/macosx/KeyboardBacklight.h |  51 ++++++++++++
> modules/gui/macosx/KeyboardBacklight.m | 145 +++++++++++++++++++++++++++++++++
> modules/gui/macosx/Modules.am          |   3 +
> modules/gui/macosx/intf.m              |   9 ++
> modules/gui/macosx/macosx.m            |   4 +
> 6 files changed, 233 insertions(+), 2 deletions(-)
> create mode 100644 modules/gui/macosx/KeyboardBacklight.h
> create mode 100644 modules/gui/macosx/KeyboardBacklight.m
> 
> diff --git a/modules/gui/macosx/CoreInteraction.m b/modules/gui/macosx/CoreInteraction.m
> index 5d13a5f..ca214f8 100644
> --- a/modules/gui/macosx/CoreInteraction.m
> +++ b/modules/gui/macosx/CoreInteraction.m
> @@ -25,6 +25,7 @@
> #import "intf.h"
> #import "open.h"
> #import "playlist.h"
> +#import "KeyboardBacklight.h"
> #import <math.h>
> #import <vlc_playlist.h>
> #import <vlc_input.h>
> @@ -617,15 +618,33 @@ static VLCCoreInteraction *_o_sharedInstance = nil;
>     if (!p_intf)
>         return;
> 
> +    BOOL b_fs;
>     vout_thread_t *p_vout = getVoutForActiveWindow();
>     if (p_vout) {
> -        BOOL b_fs = var_ToggleBool(p_vout, "fullscreen");
> +        b_fs = var_ToggleBool(p_vout, "fullscreen");
>         var_SetBool(pl_Get(p_intf), "fullscreen", b_fs);
>         vlc_object_release(p_vout);
>     } else { // e.g. lion fullscreen toggle
> -        BOOL b_fs = var_ToggleBool(pl_Get(p_intf), "fullscreen");
> +        b_fs = var_ToggleBool(pl_Get(p_intf), "fullscreen");
>         [[[VLCMain sharedInstance] voutController] setFullscreen:b_fs forWindow:nil withAnimation:YES];
>     }
> +
> +    input_thread_t *p_input = pl_CurrentInput(VLCIntf);
> +    if (p_input) {
> +        BOOL b_vplay = (var_GetInteger(p_input, "state") == PLAYING_S);
> +
> +        // Dim keyboard backlight if we're going to fullscreen and a video is playing.
> +        if (var_InheritBool(VLCIntf, "macosx-dim-keyboard") && b_fs && b_vplay) {
> +            [NSThread detachNewThreadSelector:@selector(lightsDown) toTarget:[KeyboardBacklight sharedInstance] withObject:nil];
> +        }
> +
> +        // Restore keyboard backlight if we're exiting fullscreen.
> +        if (var_InheritBool(VLCIntf, "macosx-dim-keyboard") && !b_fs) {
> +            [NSThread detachNewThreadSelector:@selector(lightsUp) toTarget:[KeyboardBacklight sharedInstance] withObject:nil];
> +        }
> +
> +        vlc_object_release(p_input);
> +    }
> }

This looks overly complicated (Why reading the „state“ variable here?) and seems the wrong place for integration. This code path is not called if the fullscreen state gets changed by other interfaces, so you miss some events here.

I think it would be better if you plug it into VoutWindowController (setFullscreen:… and removeVoutforDisplay:). Here you should not miss any events and you can omit the checks if a video actually exists.

> 
> #pragma mark - uncommon stuff
> diff --git a/modules/gui/macosx/KeyboardBacklight.h b/modules/gui/macosx/KeyboardBacklight.h
> new file mode 100644
> index 0000000..6f2ca1c
> --- /dev/null
> +++ b/modules/gui/macosx/KeyboardBacklight.h
> @@ -0,0 +1,51 @@
> +/*****************************************************************************
> + * 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
> +
> ++ (instancetype)sharedInstance;
> +
> +/*!
> + *  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;
> +
> + at end
> diff --git a/modules/gui/macosx/KeyboardBacklight.m b/modules/gui/macosx/KeyboardBacklight.m
> new file mode 100644
> index 0000000..739998c
> --- /dev/null
> +++ b/modules/gui/macosx/KeyboardBacklight.m
> @@ -0,0 +1,145 @@
> +/*****************************************************************************
> + * 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;
> +    float lastBrightnessLevel;
> +}
> +
> ++ (instancetype)sharedInstance {
> +    static id sharedInstance = nil;
> +
> +    static dispatch_once_t onceToken;
> +    dispatch_once(&onceToken, ^{
> +        sharedInstance = [[[self class] alloc] init];
> +    });
> +
> +    return sharedInstance;
> +}
> +
> +- (id)init {
> +    dataPort = [self getDataPort];
> +    lastBrightnessLevel = [self getBrightness];
> +    return self;
> +}
> +
> +- (void)dealloc {
> +    [dataPort release];

This looks wrong. according to docu, dataPort needs to be released with IOServiceClose.

> +    [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 {
> +    @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 {
> +    @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];
> +    }
> +}
> +
> + 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/intf.m b/modules/gui/macosx/intf.m
> index 678952b..104a9af 100644
> --- a/modules/gui/macosx/intf.m
> +++ b/modules/gui/macosx/intf.m
> @@ -63,6 +63,7 @@
> #import "ExtensionsManager.h"
> #import "BWQuincyManager.h"
> #import "ControlsBar.h"
> +#import "KeyboardBacklight.h"
> 
> #import "VideoEffects.h"
> #import "AudioEffects.h"
> @@ -1569,6 +1570,10 @@ static bool f_appExit = false;
>             }
>         }
> 
> +        if (var_InheritBool(p_intf, "macosx-dim-keyboard") && var_InheritBool(p_intf, "fullscreen") && [self activeVideoPlayback]) {
> +            [NSThread detachNewThreadSelector:@selector(lightsDown) toTarget:[KeyboardBacklight sharedInstance] withObject:nil];
> +        }
> +
>         /* 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 +1623,10 @@ static bool f_appExit = false;
>         [[self mainMenu] setPlay];
>         [o_mainwindow setPlay];
> 
> +        if (var_InheritBool(p_intf, "macosx-dim-keyboard") && var_InheritBool(p_intf, "fullscreen") && [self activeVideoPlayback]) {
> +            [NSThread detachNewThreadSelector:@selector(lightsUp) toTarget:[KeyboardBacklight sharedInstance] withObject:nil];
> +        }

Should not be needed here anymore, if you change it like said above.

> +
>         /* allow the system to sleep again */
>         if (systemSleepAssertionID > 0) {
>             msg_Dbg(VLCIntf, "releasing sleep blocker (%i)" , systemSleepAssertionID);
> 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