diff options
Diffstat (limited to 'keyboard_light.c')
-rw-r--r-- | keyboard_light.c | 186 |
1 files changed, 186 insertions, 0 deletions
diff --git a/keyboard_light.c b/keyboard_light.c new file mode 100644 index 0000000..798d624 --- /dev/null +++ b/keyboard_light.c @@ -0,0 +1,186 @@ +/* --------------------------------------------------------------------------*/ +/* */ +/* get/set the keyboard light level on Apple Mac OS X */ +/* Written by Hans-Christoph Steiner <hans@at.or.at> */ +/* */ +/* Copyright (c) 2008 Free Software Foundation */ +/* */ +/* 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. */ +/* */ +/* See file LICENSE for further informations on licensing terms. */ +/* */ +/* 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, */ +/* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +/* */ +/* --------------------------------------------------------------------------*/ + +#include <mach/mach.h> +#include <IOKit/IOKitLib.h> +#include <CoreFoundation/CoreFoundation.h> +#include <m_pd.h> + +#define DEBUG(x) +//#define DEBUG(x) x + +#define DEFAULT_DELAYTIME 250 +#define BRIGHTNESS_MAX 0xfff + +/*------------------------------------------------------------------------------ + * CLASS DEF + */ + +static t_class *keyboard_light_class; + +typedef struct _keyboard_light { + t_object x_obj; + t_float fade_time; + io_service_t io_service; + io_connect_t io_connect; +} t_keyboard_light; + + + +enum { + kGetSensorReadingID = 0, // getSensorReading(int *, int *) + kGetLEDBrightnessID = 1, // getLEDBrightness(int, int *) + kSetLEDBrightnessID = 2, // setLEDBrightness(int, int, int *) + kSetLEDFadeID = 3, // setLEDFade(int, int, int, int *) + // other firmware-related functions + verifyFirmwareID = 4, // verifyFirmware(int *) + getFirmwareVersionID = 5,// getFirmwareVersion(int *) + // other flashing-related functions + // ... +}; + +/*------------------------------------------------------------------------------ + * IMPLEMENTATION + */ + +static void keyboard_light_output(t_keyboard_light* x) +{ + DEBUG(post("keyboard_light_output");); + kern_return_t kernResult; + IOItemCount scalarInputCount = 1; + IOItemCount scalarOutputCount = 1; + SInt32 in_unknown = 0, out_brightness; + + if(x->io_connect) + { + kernResult = IOConnectMethodScalarIScalarO(x->io_connect, + kGetLEDBrightnessID, + scalarInputCount, + scalarOutputCount, + in_unknown, + &out_brightness); + if( kernResult == KERN_SUCCESS) + outlet_float(x->x_obj.ob_outlet, (t_float)out_brightness / BRIGHTNESS_MAX); + else if(kernResult == kIOReturnBusy) + pd_error(x,"[keyboard_light]: device busy"); + else + pd_error(x,"[keyboard_light]: could not read device"); + } +} + + +static void keyboard_light_float(t_keyboard_light* x, t_float f) +{ + DEBUG(post("keyboard_light_float");); + + kern_return_t kernResult; + IOItemCount scalarInputCount = 3; + IOItemCount scalarOutputCount = 1; + SInt32 in_unknown = 0, in_brightness, out_brightness; + + if(x->io_connect) + { + in_brightness = (SInt32) (f * BRIGHTNESS_MAX); + if(in_brightness < 0) + in_brightness = 0; + else if(in_brightness > BRIGHTNESS_MAX) + in_brightness = BRIGHTNESS_MAX; + + kernResult = IOConnectMethodScalarIScalarO(x->io_connect, + kSetLEDFadeID, + scalarInputCount, + scalarOutputCount, + in_unknown, + in_brightness, + (SInt32) x->fade_time, + &out_brightness); + if( kernResult != KERN_SUCCESS) + { + if(kernResult == kIOReturnBusy) + pd_error(x,"[keyboard_light]: device busy"); + else + pd_error(x,"[keyboard_light]: could not write to device"); + } + } +} + + +static void keyboard_light_free(t_keyboard_light* x) +{ + DEBUG(post("keyboard_light_free");); +} + + +static void *keyboard_light_new(void) +{ + DEBUG(post("keyboard_light_new");); + t_keyboard_light *x = (t_keyboard_light *)pd_new(keyboard_light_class); + kern_return_t kernResult; + + x->io_service = IOServiceGetMatchingService(kIOMasterPortDefault, + IOServiceMatching("AppleLMUController")); + if(x->io_service) + { + post("[keyboard_light]: found AppleLMUController"); + } + else + { + error("[keyboard_light]: AppleLMUController not found, trying IOI2CDeviceLMU"); + x->io_service = IOServiceGetMatchingService(kIOMasterPortDefault, + IOServiceMatching("IOI2CDeviceLMU")); + if(x->io_service) + { + post("[keyboard_light]: found IOI2CDeviceLMU"); + } + else + pd_error(x,"[keyboard_light]: no sensor found"); + } + kernResult = IOServiceOpen(x->io_service, mach_task_self(), 0, &x->io_connect); + + IOObjectRelease(x->io_service); + if (kernResult != KERN_SUCCESS) + { + error("[keyboard_light]: IOServiceOpen(): %d", kernResult); + } + + x->fade_time = 0.; + floatinlet_new(&x->x_obj, &x->fade_time); + outlet_new(&x->x_obj, &s_float); + + return (x); +} + +void keyboard_light_setup(void) +{ + keyboard_light_class = class_new(gensym("keyboard_light"), + (t_newmethod)keyboard_light_new, + (t_method)keyboard_light_free, + sizeof(t_keyboard_light), + CLASS_DEFAULT, + A_DEFFLOAT, 0); + /* add inlet datatype methods */ + class_addbang(keyboard_light_class,(t_method) keyboard_light_output); + class_addfloat(keyboard_light_class,(t_method) keyboard_light_float); +} |