views:

55

answers:

2

For such a basic question, I'm surprised I couldn't find anything by searching...

Anyways, I made a curses app in Python that assists in solving puzzles of a certain DSiWare game. With it, you can take a puzzle and inspect the components of it individually. The keys qweasdzx are used to paint tiles (the keys are arranged in some sort of palette). Pressing one of these keys while holding Shift highlights tiles with that color. I couldn't ask for a more natural control scheme.

So it's a shame that, once again, Shift is giving me issues (last time I had issues with Shift, I earned a Tumbleweed badge). Though this time, the problem is more or less Caps Lock, which completely screws up my program by reversing the functions.

How can I detect the state of Caps Lock in Python with curses?

EDIT: If you're going to suggest using a separate module, I probably should remind you that curses - and therefore my program - is in UNIX territory.

+1  A: 

The short answer: you can't.

A longer answer:

curses was created as a terminfo-based library to ease the creation of character-based UIs independent of the terminal used (for terminal in 'vt220', 'wyse100', …).

These terminals connected through a serial line and the communication to-and-fro the host were through either plain text (input by the user or output by the host) or special sequences ("escape" sequences; input by the user if special keys were pressed, like or Prev, or output by the host if special operations like cursor positioning or screen clearing was requested).

I have no knowledge of any dumb terminal sending a special sequence whenever the Caps Lock key was depressed, or the host querying for the Caps Lock status; locking capitals was part of the job of the terminal, and the host had no need for any knowledge. This is similar to the reason you can't have a curses program act when the Control key is depressed on its own.

Everything about curses relates to terminfo capabilities; there isn't any related capability for what you ask.

ΤΖΩΤΖΙΟΥ
+2  A: 

I found a solution on my own:

Since curses is completely unaware of the Caps Lock setting according to ΤΖΩΤΖΙΟΥ, I tried an alternative solution. Specifically, I looked up how to check Caps Lock in a BASH script. What I found was this:

Linux only. Requires X Window System.

$ xset q | grep LED
>  auto repeat:  on    key click percent:  0    LED mask:  00000000

The last 0 in that output (the 66th character in the string) is the Caps Lock flag. 1 if it's on, 0 if it's off.

Python can run UNIX system commands with the Linux-only commands module. commands does not appear to interfere with curses.

>>> import commands
>>> # Caps Lock is off.
>>> commands.getoutput("xset q | grep LED")[65]
'0'
>>> # Setting Caps Lock on now.
>>> commands.getoutput("xset q | grep LED")[65]
'1'

This works fine for me; this is a personal-use script, and it's not like my program wasn't already Linux-exclusive. But I do hope somebody has another, more Windows-compatible solution.

I'm going to accept this self-answer for now, but if somebody else can come up with a better working solution, I'd like to see it.

Exp HP
+1: This *is* a solution to your problem, so I'm upvoting; you'll have to accumulate first some reputation, though, before being able to mark your own answer as *the answer*.
ΤΖΩΤΖΙΟΥ
It looks like time is the sole factor in determining whether or not one can accept his/her own answer, as I was able to accept this after 48 hours. I'd like to note to other users that even though I've accepted this answer, I'd gladly change my selection if somebody else visiting this question comes up with a better answer.
Exp HP
Be aware that this solution will only work if you are running under X windows. It won't work on the linux console and it won't work if you remotely connect (i.e. ssh) to the system (without X forwarding of some sort)
Craig
@Craig: Duly noted.
Exp HP