Python script for Windows to control ThinkPad features

From ThinkWiki
Revision as of 20:42, 12 March 2008 by Yak (Talk | contribs)
Jump to: navigation, search

This is a Python module for Windows that can control the volume, LCD brightness, ThinkLight, magnification (Fn+Space) and ThinkPad Button. It is based on the ctypes module (which is included by default with Python 2.5 and later). The ThinkPad Hotkey Features software from IBM/Lenovo must be installed. If the OSD is enabled, it will appear while changing the values using this module.

Since the script uses direct Win32 API calls, it should be pretty straightforward to base a program with similar functionality written in a different language on this script.

thinkpad.py

# Author: Arkadiusz Wahlig
# License: public domain

import sys
from ctypes import *

class Hotkeys:
    def __init__(self):
        assert sys.platform == 'win32', 'Only win32 platform supported!'
        path = r'\\.\TPHKDRV'
        if sys.getwindowsversion()[3] != 2:
            # the path is different for Win 95/98/ME
            path += '.VXD'
        self.k32 = windll.kernel32
        self.dev = self.k32.CreateFileA(path, 0xC0000000, 3, 0, 3, 0, 0)
        if self.dev == 0xffffffff:
            raise IOError('Cannot open TPHKDRV.SYS driver!')

    def __del__(self):
        self.k32.CloseHandle(self.dev)

    def doio(self, ctrl, x):
        b_in = c_ulong(x)
        b_out = c_ulong()
        numbytes = c_ulong()
        if not self.k32.DeviceIoControl(self.dev, ctrl, byref(b_in), 4, byref(b_out), 4, byref(numbytes), 0):
            raise IOError('DeviceIoControl() failed!')
        return b_out.value

    def get(self, var):
        return self.doio(0x81008128, var)

    def set(self, var, value):
        self.doio(0x8100812c, (var << 24) | value)

    def is_thinklight_available(self):
        return bool(self.doio(0x81008120, 0) & 0x4000000)

    def get_thinklight(self):
        return bool(self.get(0x1a) & 0xff)

    def set_thinklight(self, on):
        self.set(0x1a, int(on))

    def get_brightness(self):
        return int(self.get(0xc) & 0xff)

    def set_brightness(self, brightness):
        self.set(0xc, brightness & 0xff)

    def get_volume(self):
        return int(self.get(0xe) & 0xff)

    def set_volume(self, volume):
        self.set(0xe, volume & 0xff)

    def get_mute(self):
        return bool(self.get(0x10) & 0xff)

    def set_mute(self, mute):
        self.set(0x10, int(mute))

    def get_magnify(self):
        return bool(self.get(0x16) & 0xff)

    def set_magnify(self, on):
        self.set(0x16, int(on))

    def get_accessibm(self):
        return bool(self.get(0x18) & 0xff)

Example: blinking the ThinkLight

This script uses the above module to blink the ThinkLight. The original state of the light is restored afterwards.

import thinkpad
import time

hk = thinkpad.Hotkeys()
old = hk.get_thinklight()
for i in range(6):
    hk.set_thinklight(True)
    time.sleep(0.2)
    hk.set_thinklight(False)
    time.sleep(0.2)
hk.set_thinklight(old)