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

David Fuhrmann david.fuhrmann at gmail.com
Fri May 8 18:35:20 CEST 2015


Hello Maxime,

Thanks for this cool patch. Does this work with all supported OS X versions (>= 10.6)?

Generally, did you consider only dimming the light when the VLC video is in fullscreen mode? Because in windowed mode, the rest of the monitor will probably so bright that it does not really make sense to dim the keyboard (and maybe the user wants to use it still).

Please also see some minor remarks about your patch inline.

> Am 08.05.2015 um 10:58 schrieb Maxime Mouchet <max at maxmouchet.com>:
> 
> This patch adds the option to turn off the keyboard backlight when
> a video is playing, 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.
> ---
> modules/gui/macosx/KeyboardBacklight.h |  51 +++++++++++++
> modules/gui/macosx/KeyboardBacklight.m | 136 +++++++++++++++++++++++++++++++++
> modules/gui/macosx/Modules.am          |   3 +
> modules/gui/macosx/intf.m              |   9 +++
> modules/gui/macosx/macosx.m            |   4 +
> 5 files changed, 203 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..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..d65df87
> --- /dev/null
> +++ b/modules/gui/macosx/KeyboardBacklight.m
> @@ -0,0 +1,136 @@
> +/*****************************************************************************
> + * 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;
> +}
> +
> +- (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);

From what I got from the documentation, you should also destroy dataPort later on again, probably in dealloc?

> +
> +    if (kr != KERN_SUCCESS) { return 0; }
> +
> +    return dataPort;
> +}
> +
> +- (void)setBrightness:(float)brightness {
> +    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);

For all these calls, should you check before if dataPort is valid and not 0?

> +
> +    if (kr != KERN_SUCCESS) { return; }
> +}
> +
> +- (float)getBrightness {
> +    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..ea76def 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 ([self activeVideoPlayback] && config_GetInt(VLCIntf, "macosx-dim-keyboard")) {
> +            [NSThread detachNewThreadSelector:@selector(lightsDown) toTarget:[KeyboardBacklight sharedInstance] withObject:nil];
> +        }

Please use var_InheritBool.

> +
>         /* 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 ([self activeVideoPlayback] && config_GetInt(VLCIntf, "macosx-dim-keyboard")) {
> +            [NSThread detachNewThreadSelector:@selector(lightsUp) toTarget:[KeyboardBacklight sharedInstance] withObject:nil];
> +        }
> +
>         /* 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..8c9451f 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 playback")
> +#define DIM_KEYBOARD_PLAYBACK_LONGTEXT N_("Turn off the MacBook keyboard backlight while a video is playing. 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.3.5

Best regards,
David


More information about the vlc-devel mailing list