Skip to content

Commit 91b7f3f

Browse files
author
ftk
committed
initial
0 parents  commit 91b7f3f

File tree

5 files changed

+142
-0
lines changed

5 files changed

+142
-0
lines changed

.gitattributes

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# Auto detect text files and perform LF normalization
2+
* text=auto

Makefile

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
2+
# compile without c runtime library to make binary super small (~3k)
3+
kbled.exe: kbled2.c
4+
gcc -Dmain=mainCRTStartup -std=c11 -nostdlib -mwindows $< -o $@ -luser32 -lkernel32 -Ofast -march=native -s -fvisibility=hidden -fno-ident

kbled.c

+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
#include <windows.h>
2+
#include <stdbool.h>
3+
4+
static const int vkey_scroll = 0x91,
5+
scan_scroll = 0x46;
6+
7+
static void press_scroll()
8+
{
9+
keybd_event(vkey_scroll, scan_scroll, KEYEVENTF_EXTENDEDKEY, 0);
10+
keybd_event(vkey_scroll, scan_scroll, KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, 0);
11+
}
12+
13+
static bool get_scroll()
14+
{
15+
return GetKeyState(vkey_scroll) & 1;
16+
}
17+
18+
19+
int main(void)
20+
{
21+
{
22+
MSG msg;
23+
if(PostThreadMessage(GetCurrentThreadId(), 0, 0, 0))
24+
GetMessage(&msg, 0, 0, 0);
25+
}
26+
27+
while(1)
28+
{
29+
bool en_us = LOWORD(GetKeyboardLayout(GetWindowThreadProcessId(GetForegroundWindow(), NULL))) == 0x0409;
30+
if(en_us == get_scroll()) // en_us - scroll off, else on
31+
{
32+
press_scroll();
33+
}
34+
Sleep(200);
35+
}
36+
return 0;
37+
}
38+
39+
40+

kbled2.c

+87
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
#include <windows.h>
2+
#include <stdbool.h>
3+
4+
static const int vkey_scroll = 0x91, // scroll lock virtual key
5+
scan_scroll = 0x46, // scroll lock scancode
6+
en_us_layout = 0x0409; // en_US layout (from MSDN)
7+
8+
static void press_scroll()
9+
{
10+
keybd_event(vkey_scroll, scan_scroll, KEYEVENTF_EXTENDEDKEY, 0);
11+
keybd_event(vkey_scroll, scan_scroll, KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, 0);
12+
}
13+
14+
static bool get_scroll()
15+
{
16+
return GetKeyState(vkey_scroll) & 1;
17+
}
18+
19+
20+
int main(void)
21+
{
22+
{
23+
// stop loading animation
24+
MSG msg;
25+
if(PostThreadMessage(GetCurrentThreadId(), 0, 0, 0))
26+
GetMessage(&msg, 0, 0, 0);
27+
}
28+
29+
HKL prev_hkl;
30+
DWORD prev_thread; // thread id
31+
bool prev_en_us = true;
32+
while(1)
33+
{
34+
Sleep(100);
35+
36+
HWND cur_window = GetForegroundWindow();
37+
if(cur_window == NULL) // switching windows
38+
continue;
39+
DWORD cur_thread = GetWindowThreadProcessId(cur_window, NULL);
40+
HKL cur_hkl = GetKeyboardLayout(cur_thread);
41+
bool en_us = LOWORD(cur_hkl) == en_us_layout;
42+
43+
#if 0 // method 1
44+
if(prev_en_us != en_us && cur_thread != prev_thread) // switched to other process with different layout
45+
{
46+
// change fg window layout
47+
//ActivateKeyboardLayout(prev_hkl, KLF_ACTIVATE | KLF_SETFORPROCESS); - doesn't work (changes for our process probably)
48+
49+
PostMessage(cur_window,
50+
WM_INPUTLANGCHANGEREQUEST,
51+
0,
52+
(LPARAM)prev_hkl);
53+
en_us = prev_en_us;
54+
cur_hkl = prev_hkl;
55+
}
56+
#else // method 2
57+
if(prev_en_us != en_us && cur_thread == prev_thread) // switched layout manually
58+
{
59+
// send all windows message to switch their layout
60+
// (by default windows sends it only to the current window (?))
61+
PostMessage(HWND_BROADCAST,
62+
WM_INPUTLANGCHANGEREQUEST,
63+
0,
64+
(LPARAM)cur_hkl);
65+
}
66+
#endif
67+
68+
static bool tried_pressing_scroll = false;
69+
if(prev_en_us != en_us || prev_thread != cur_thread)
70+
tried_pressing_scroll = false;
71+
// setup light
72+
if(!tried_pressing_scroll && en_us == get_scroll()) // en_us - scroll off, else on
73+
{
74+
press_scroll();
75+
tried_pressing_scroll = true; // dont spam scroll presses if fg program doesnt handle it correctly (emacs...)
76+
}
77+
78+
79+
prev_en_us = en_us;
80+
prev_thread = cur_thread;
81+
prev_hkl = cur_hkl;
82+
83+
}
84+
return 0;
85+
}
86+
87+

readme.txt

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
kbled is a small program for Windows to indicate current keyboard layout using scroll lock light on keyboard.
2+
kbled2 also makes keyboard layout system-wide (in Windows prior to Windows 8(?) keyboard layout is local for each application).
3+
4+
Installation:
5+
1. Compile with C99 or C++ compiler
6+
2. Put the binary in Startup folder
7+
8+
Known bugs:
9+
* currently doesn't work with default Windows terminal

0 commit comments

Comments
 (0)