/* --------------------------------------------------------------------------*/ /* */ /* 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(t_float level, t_float fade_time) { 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 = fade_time; floatinlet_new(&x->x_obj, &x->fade_time); outlet_new(&x->x_obj, &s_float); keyboard_light_float(x, level); 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, 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); }