From 042552ed6790e7c9edc35b80819307c96c6134ee Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Wed, 12 Mar 2008 18:30:05 +0000 Subject: completed object to query and control the lights on the keyboards of Apple hardware svn path=/trunk/externals/apple/; revision=9574 --- apple | 1 + keyboard_light-help.pd | 25 +++++++ keyboard_light.c | 186 +++++++++++++++++++++++++++++++++++++++++++++++++ keyboard_light.libs | 1 + 4 files changed, 213 insertions(+) create mode 120000 apple create mode 100644 keyboard_light-help.pd create mode 100644 keyboard_light.c create mode 100644 keyboard_light.libs diff --git a/apple b/apple new file mode 120000 index 0000000..945c9b4 --- /dev/null +++ b/apple @@ -0,0 +1 @@ +. \ No newline at end of file diff --git a/keyboard_light-help.pd b/keyboard_light-help.pd new file mode 100644 index 0000000..2af1f34 --- /dev/null +++ b/keyboard_light-help.pd @@ -0,0 +1,25 @@ +#N canvas 0 22 506 356 10; +#X msg 136 78 bang; +#X obj 159 117 hsl 128 15 0 1 0 0 empty empty empty -2 -6 0 10 -262144 +-1 -1 8000 0; +#X floatatom 136 291 5 0 0 0 - - -; +#X obj 136 247 apple/keyboard_light; +#X text 294 116 light level; +#X obj 256 148 hsl 128 15 40 4000 1 0 empty empty empty -2 -6 0 10 +-262144 -1 -1 0 0; +#X text 391 147 fade time; +#X floatatom 270 173 5 0 0 0 - - -; +#X floatatom 165 140 5 0 0 0 - - -; +#X text 26 23 Control the keyboard lights on Apples.; +#X text 178 77 get current leve; +#X text 210 206 set level and fade as a list; +#X msg 165 217 0 50; +#X msg 161 195 1 1000; +#X connect 0 0 3 0; +#X connect 1 0 3 0; +#X connect 1 0 8 0; +#X connect 3 0 2 0; +#X connect 5 0 3 1; +#X connect 5 0 7 0; +#X connect 12 0 3 0; +#X connect 13 0 3 0; 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 */ +/* */ +/* 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 +#include +#include +#include + +#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); +} diff --git a/keyboard_light.libs b/keyboard_light.libs new file mode 100644 index 0000000..334d5d6 --- /dev/null +++ b/keyboard_light.libs @@ -0,0 +1 @@ +-framework IOKit -- cgit v1.2.1