Page 1 of 1

Detecting if Keylock is on?

Posted: Fri Jan 19, 2024 4:03 pm
by Silver_Wolf
Is there a method of checking whether or not a keylock is on such as: Capslock, Scrolllock, Numlock?

Re: Detecting if Keylock is on?

Posted: Fri Jan 19, 2024 6:08 pm
by keharriso

Re: Detecting if Keylock is on?

Posted: Sat Jan 20, 2024 12:25 am
by RNavega
Nice, didn't know about that one.
Up to this moment it looks to be in the Löve 12.0 development branch, the source is this:
https://github.com/love2d/love/blob/12. ... p#L88-L107

@Silver_Wolf what are you trying to do with those switches? Maybe there's a simpler way.
I don't think it's possible to truly know their state Edit: I was wrong, SDL does start with a correct state, pretty cool. Read the asterisk below.

* The program starts with SDL's internal keyboard state being the same as the operating system's, so that if NumLock is active when your program started, the internal SDL state for that modifier is active as well.
On Windows at least, the relevant code that sets this up is in here: https://github.com/libsdl-org/SDL/blob/ ... #L376-L378

Re: Detecting if Keylock is on?

Posted: Sat Jan 20, 2024 2:27 am
by Silver_Wolf
I have to know if scrolllock is on for what I am trying to do as knowing the state of scrolllock is important to what I am doing. There is no way around it.

love.keyboard.isModiferActive(capslock)

doesn't seem to be working, getting "attempt to index field 'keyboard' (a nil value)"

I just realized it's LOVE 12.0 and I have no idea how to check which version ZeroBrane is using.

Okay, I only have 11.5 and I don't know how to get 12.0

Re: Detecting if Keylock is on?

Posted: Sat Jan 20, 2024 4:25 am
by RNavega
That's okay.
If ZeroBrane is using the latest official release of Löve, 11.5, then as you noticed it won't have love.keyboard.isModifierActive.
But using LuaJIT's FFI module, you can create a backport of love.keyboard.isModifierActive directly in a Lua script, like this:

Code: Select all

io.stdout:setvbuf('no')


local bit = require('bit')
local band = bit.band

local ffi = require('ffi')
-- Based on:
-- https://github.com/torch/sdl2-ffi/blob/master/cdefs.lua#L1407-L1432
ffi.cdef([[
// Using 'unsigned int' instead of "SDL_Keymod" for brevity.
unsigned int SDL_GetModState(void);
]])

-- Based on:
-- https://github.com/libsdl-org/SDL/blob/SDL2/include/SDL_keycode.h#L332
local SDL_Keymod = {
    KMOD_NONE = 0x0000,
    KMOD_LSHIFT = 0x0001,
    KMOD_RSHIFT = 0x0002,
    KMOD_LCTRL = 0x0040,
    KMOD_RCTRL = 0x0080,
    KMOD_LALT = 0x0100,
    KMOD_RALT = 0x0200,
    KMOD_LGUI = 0x0400,
    KMOD_RGUI = 0x0800,
    KMOD_NUM = 0x1000,
    KMOD_CAPS = 0x2000,
    KMOD_MODE = 0x4000,
    KMOD_SCROLL = 0x8000,
    
    KMOD_CTRL = 0x0040 + 0x0080,
    KMOD_SHIFT = 0x0001 + 0x0002,
    KMOD_ALT = 0x0100 + 0x0200,
    KMOD_GUI = 0x0400 + 0x0800,

    KMOD_RESERVED = 0x8000
}

-- Cross-platform SDL reference from here:
-- https://love2d.org/forums/viewtopic.php?p=252728#p252728
local SDL = (ffi.os == "Windows" and ffi.load("SDL2") or ffi.C)
local SDL_GetModState = SDL.SDL_GetModState


function love.keyboard.isModifierActive(key)
    if key == 'capslock' then
        return band(SDL_GetModState(), SDL_Keymod.KMOD_CAPS) ~= 0
    elseif key == 'numlock' then
        return band(SDL_GetModState(), SDL_Keymod.KMOD_NUM) ~= 0
    elseif key == 'scrolllock' then
        return band(SDL_GetModState(), SDL_Keymod.KMOD_SCROLL) ~= 0
    elseif key == 'mode' then
        return band(SDL_GetModState(), SDL_Keymod.KMOD_MODE) ~= 0
    end
    return false
end


print('The program started with:')
print()
print('Capslock:', love.keyboard.isModifierActive('capslock'))
print('NumLock:', love.keyboard.isModifierActive('numlock'))
print('ScrollLock:', love.keyboard.isModifierActive('scrolllock'))
print('Mode:   ', love.keyboard.isModifierActive('mode'))


function love.keypressed()
    love.event.quit()
end


function love.draw()
    love.graphics.print('Look in the system console.', 10, 10)
    love.graphics.print('Press any key to quit.', 10, 30)
end
...then when 12.0 is offically released, you can remove all of that and use the built-in.