Difference between revisions of "Python script for Windows to control ThinkPad features"

From ThinkWiki
Jump to: navigation, search
(Updated thinkpad.py)
Line 10: Line 10:
 
  from ctypes import *
 
  from ctypes import *
 
   
 
   
  class HotkeyDriver:
+
  class Hotkeys:
 
     def __init__(self):
 
     def __init__(self):
 
         assert sys.platform == 'win32', 'Only win32 platform supported!'
 
         assert sys.platform == 'win32', 'Only win32 platform supported!'
Line 20: Line 20:
 
         self.dev = self.k32.CreateFileA(path, 0xC0000000, 3, 0, 3, 0, 0)
 
         self.dev = self.k32.CreateFileA(path, 0xC0000000, 3, 0, 3, 0, 0)
 
         if self.dev == 0xffffffff:
 
         if self.dev == 0xffffffff:
             raise IOError('Cannot open ThinkPad hotkey driver!')
+
             raise IOError('Cannot open TPHKDRV.SYS driver!')
 
   
 
   
 
     def __del__(self):
 
     def __del__(self):
Line 29: Line 29:
 
         b_out = c_ulong()
 
         b_out = c_ulong()
 
         numbytes = c_ulong()
 
         numbytes = c_ulong()
         self.k32.DeviceIoControl(self.dev, ctrl, byref(b_in), 4, byref(b_out), 4, byref(numbytes), 0)
+
         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
 
         return b_out.value
 
   
 
   
Line 42: Line 43:
 
   
 
   
 
     def get_thinklight(self):
 
     def get_thinklight(self):
         return bool(self.get(0x1a) & 1)
+
         return bool(self.get(0x1a) & 0xff)
 
   
 
   
 
     def set_thinklight(self, on):
 
     def set_thinklight(self, on):
Line 60: Line 61:
 
   
 
   
 
     def get_mute(self):
 
     def get_mute(self):
         return bool(self.get(0x10) & 1)
+
         return bool(self.get(0x10) & 0xff)
 
   
 
   
 
     def set_mute(self, mute):
 
     def set_mute(self, mute):
 
         self.set(0x10, int(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==
 
==Example: blinking the ThinkLight==

Revision as of 21:37, 12 March 2008

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