Python script for Windows to control ThinkPad features

From ThinkWiki
Revision as of 03:07, 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 and ThinkLight of a ThinkPad. 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.

thinkpad.py

# Author: Arkadiusz Wahlig
# License: public domain

import sys
from ctypes import *

class HotkeyDriver:
    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 ThinkPad hotkey 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()
        self.k32.DeviceIoControl(self.dev, ctrl, byref(b_in), 4, byref(b_out), 4, byref(numbytes), 0)
        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) & 1)

    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) & 1)

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

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.HotkeyDriver()
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)