Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
keyboard issue ? SHIFT + TAB not detected (linux)
#11
Hi,

Here is a new program under Linux that retrieves the keycode of the pressed key and translates it into keysym and Unicode.

Code: (Select All)
' ========================================================================================
' This program is designed to manage the X11 keymap and interpret keyboard input,
' specifically focusing on printing the Unicode characters of pressed keys.
'
' It retrieves the current keymap using the xmodmap command, parses keycodes and
' their corresponding keysyms, and stores this information in structured data types.
'
' By tracking modifier states, the program accurately maps key events to their Unicode
' representations, allowing it to output the correct characters and their names to the
' console when keys are pressed.
'
' You can test this program after changing the keyboard language with setxkbmap.
'
' This program read raw keyboard events directly from a Linux input device file, typically
' located at `/dev/input/event0`. Modify keyboardFileName$ to change input device file.
'
' It is a low-level approach that bypasses standard input methods to capture every key
' press, release, and repeat event.
' ========================================================================================

' Structure to hold the current X11 keymap

type keymapType
    keycode as _unsigned _byte  ' xmodmap keycode adjusted (stored as keycode - 8)
    keysym2 as string            ' keysym for level 1 (no modifier)
    name2 as string              ' human-readable name for keysym2
    keysym3 as string            ' keysym for level 2 (Shift)
    name3 as string              ' human-readable name for keysym3
    keysym4 as string            ' keysym for level 3 (AltGr / Mode_switch)
    name4 as string              ' human-readable name for keysym4
    keysym5 as string            ' keysym for level 4 (Shift + AltGr)
    name5 as string              ' human-readable name for keysym5
end type

' Structure to hold a keysym definition parsed from keysymdef.h

type keysymdefType
    symname as string  ' The keysym name (e.g. "XK_A" without the "XK_" prefix in this code)
    symcode as string  ' The keysym constant value as found in the header (e.g. "0xff41")
    unicode as string  ' Optional Unicode mapping token (e.g. "U+0061") if present
end type

$console
_dest _console

' Execute the system command "xmodmap -pk" to get the current X11 keymap
' and extract keycodes, keysyms or names

shell "xmodmap -pk > ./keyboardWithXmodmap.tmp"
content$ = _readfile$("./keyboardWithXmodmap.tmp")
kill "./keyboardWithXmodmap.tmp"

redim xmodmap$(0)
split content$, _STR_NAT_EOL, xmodmap$()
clean xmodmap$()

dim keymap(8 to 255) as keymapType

for i%=3 to ubound(xmodmap$)
    replace xmodmap$(i%), chr$(9), chr$(32)
    redim keyCodeAndSym$(0)
    split xmodmap$(i%), " ", keyCodeAndSym$()
    k% = val(keyCodeAndSym$(0))
    keymap(k%).keycode = k% - 8
    if ubound(keyCodeAndSym$)>5 then
        keymap(k%).keysym2 = keyCodeAndSym$(5)
        keymap(k%).name2 = keyCodeAndSym$(6)
    end if
    if ubound(keyCodeAndSym$)>7 then
        keymap(k%).keysym3 = keyCodeAndSym$(7)
        keymap(k%).name3 = keyCodeAndSym$(8)
    end if
    if ubound(keyCodeAndSym$)>9 then
        keymap(k%).keysym4 = keyCodeAndSym$(9)
        keymap(k%).name4 = keyCodeAndSym$(10)
    end if
    if ubound(keyCodeAndSym$)>11 then
        keymap(k%).keysym5 = keyCodeAndSym$(11)
        keymap(k%).name5 = keyCodeAndSym$(12)
    end if
next i%

' Get X11 keysym definitions from /usr/include/X11/keysymdef.h into ks() array

dim ks(2200) as keysymdefType

l% = 1

open "/usr/include/X11/keysymdef.h" for input as #1

do while not eof(1)
    line input #1, content$
    redim r$(0)
    split content$, " ",  r$()
    if ubound(r$) = 0 then _continue
    if left$(r$(lbound(r$)),7) <> "#define" then _continue
    ks(l%).symname = mid$(r$(lbound(r$)+1),4)
    ks(l%).symcode = r$(lbound(r$)+2)
    for i% = lbound(r$)+3 to ubound(r$)
        if left$(r$(i%),2) = "U+" then ks(l%).unicode = r$(i%)
    next i%
    l% = l% + 1
loop

close #1

screen _NewImage(1024,768,32)

' load the first monospace font

shell "fc-list Confusedpacing=100Confusedtyle=bold:lang=fr | head -n 1 | cut -d: -f1 > ./keyboardWithXmodmap.tmp"
open "./keyboardWithXmodmap.tmp" for input as #1
line input #1, fontFile$
close #1
kill "./keyboardWithXmodmap.tmp"

DIM fh AS LONG:
fh = _loadfont(fontFile$,24)
IF fh <= 0 THEN
    $console
    _dest _console
    PRINT "Failed to load font file!"
    _dest 0
    END
END IF
_FONT fh

' Reads 24-byte event structures from the specified device file.
'
' It filters for key-related events and then determines if the event is a key press (DOWN_DETECTED),
' a key release (UP_DETECTED), or an auto-repeat (REPEAT_DETECTED).
'
' It specifically tracks the state of modifier keys (Left Shift, Right Shift, and Right Alt)
' to correctly interpret the character generated by other key presses.
'
' When a non-modifier key is pressed, it uses the key's scancode combined with the current state
' of the modifiers to look up the appropriate  keysym and character name from a `keymap` array (not defined in this snippet).
'
' The resulting information is then printed to the window.

const KEY_EVENT = &h01
const UP_DETECTED = 0
const DOWN_DETECTED = 1
const REPEAT_DETECTED = 2

const KEY_LEFTSHIFT = 42
const KEY_RIGHTSHIFT = 54
const KEY_RIGHTALT = 100

dim aByte(24) as _unsigned _byte

keyboardFileName$ = "/dev/input/event0"
open keyboardFileName$ for binary as #1

print "keycode", "keysym", "unicode", "char.", "name"
p% = 1
do
    get #1, , aByte(p%)
    if (p% MOD 24) = 0 then
        if aByte(17) = KEY_EVENT then
            select case aByte(21)
                case UP_DETECTED
                    select case aByte(19)
                        case KEY_LEFTSHIFT :
                            modifiers = modifiers and not 1
                        case KEY_RIGHTSHIFT :
                            modifiers = modifiers and not 1
                        case KEY_RIGHTALT :
                            modifiers = modifiers and not 2
                    end select
                case DOWN_DETECTED
                    if aByte(19) = 1 then exit do    ' Exit on ESC key down
                    select case aByte(19)
                        case KEY_LEFTSHIFT :
                            modifiers = modifiers or 1
                        case KEY_RIGHTSHIFT :
                            modifiers = modifiers or 1
                        case KEY_RIGHTALT :
                            modifiers = modifiers or 2
                        case else:
                            k% = aByte(19)+8
                            select case modifiers
                                case 0 :
                                    printData  keymap(k%).keycode, keymap(k%).keysym2, keymap(k%).name2, ks()
                                case 1 :
                                    printData  keymap(k%).keycode, keymap(k%).keysym3, keymap(k%).name3, ks()
                                case 2 :
                                    printData  keymap(k%).keycode, keymap(k%).keysym4, keymap(k%).name4, ks()
                                case 3 :
                                    printData  keymap(k%).keycode, keymap(k%).keysym5, keymap(k%).name5, ks()
                            end select
                    end select
                case REPEAT_DETECTED
                    if SHOW_ME_REPETITION then
                        print " REPEAT  ", aByte(19)
                    end if
            end select
        end if
        p% = 0
    end if
    p% = p% + 1
loop

system

' print keycode, keysym, unicode, character, character name

sub printData (keycode, keysym as string, keyname as string, ks() as keysymdefType)
    if keysym = "" then
        print keycode, space$(8), space$(8), space$(8), keyname
    end if
    uc$ = _trim$(searchKeysym(ks(),keysym))
    unicode = val("&H"+mid$(uc$,3))
    if unicode > 0 then
        _mapunicode unicode to &HFF
        print keycode, keysym, uc$, chr$(&HFF), keyname
    else
        print keycode, keysym, space$(8), space$(8), keyname
    end if
end sub

' search keysym to get the unicode equivalent

function searchKeysym$ (ks() as keysymdefType, keysym as string)
    res$ = ""
    for i% = lbound(ks) to ubound(ks)
        if ks(i%).symcode = keysym then
            res$ = ks(i%).unicode
            exit for
        end if
    next i%
    searchKeysym = res$
end function

' split string using a delimiter

Sub split (in$, delimiter$, result$())
    ReDim result$(-1)
    dim start, finish
    start = 1
    Do
        While Mid$(in$, start, 1) = delimiter$
            start = start + 1
            If start > Len(in$) Then Exit Sub
        Wend
        finish = InStr(start, in$, delimiter$)
        If finish = 0 Then finish = Len(in$) + 1
        ReDim _Preserve result$(0 To UBound(result$) + 1)
        result$(UBound(result$)) = Mid$(in$, start, finish - start)
        start = finish + 1
    Loop While start <= Len(in$)
End Sub

' clean array of string

sub clean (result$())
    dim i%
    for i% = lbound(result$) to ubound(result$)
        if right$(result$(i%),1) = chr$(13) then
            result$(i%) = left$(result$(i%),len(result$(i%))-1)
        end if 
    next i%
end sub

' replace findString with replaceString into myString

sub replace (myString$, findString$, replaceString$)
    start% = 1
    do
        position% = INSTR(start%, myString$, findString$)
        IF position% THEN
            MID$(myString$, position%, len(findString$)) = replaceString$
            start% = position% + 1
        END IF
    loop until position% = 0
end sub
Reply
#12
(08-21-2025, 10:01 PM)Herve Wrote: Here is a new program under Linux that retrieves the keycode of the pressed key and translates it into keysym and Unicode.
Very, very cool!  Thanks for sharing this!

Question:  Can something like this be done for the terminal, for instance, in an xterm?
I would love to be able to read "missing keys" there, such as ctrl-0, difference between enter and ctrl-m, backspace and ctrl-h, tab and ctrl-i, and so on.

Any ideas?
Thank you.
Reply
#13
it will have to be tested in wayland session.  especially in gnome or kde.

because many things are done already.  for wayland compositor.  to avoid the "security problems allowed by x11."  this has been an excuse i've kept reading in various forms.  for supporting wayland over "legacy."

i have used (tested) a fair amount of linux distributions.  most of them based on debian.  so i have noticed a transition from "synclient" to "xinput"/"libinput" to handle touchpad.  i have a computer which is almost 15 years old.  started with windows8 installed on it.  now has windows10.  rarely go into it anymore.  instead into debian 12 with mate desktop.  especially if i want to use kde plasma instead.  "synclient" is not expected to be installed.  but it is expected.  for example on mx linux with fluxbox.  or on anything with lxde.  it's becoming a bit of a mess on lxqt.  especially if it's not debian's.  which uses xfce's window manager.  instead of openbox.  for example on opensuse.  lxqt uses openbox.  which then creates an issue.  requiring the user to decide between "synclient" and "xinput."  but this is only about the touchpad.

handling the keyboard.  for example to tell "ctrl+m" from "enter" could be a dangerous proposition on an unix descendant.  that's what the "security pundits" in favor of wayland.  and for totally trashing "x11" would tell you now.
Reply
#14
Hi,

Here is a version that takes into account the Ctrl and Caps Lock keys.
I have also added console output in addition to the application window. 

@Ed Davis
As for the possibility of launching the application in xterm, yes, it works, but you must first launch xterm with a TTF font that contains the Unicode glyphs. For example:

Code: (Select All)
xterm -fa 'Liberation Mono' -fs 10

@hsiangch_ong
Regarding Wayland, I will test it when I have access to a virtual machine.

Code: (Select All)
' ========================================================================================
' This program is designed to manage the X11 keymap and interpret keyboard input,
' specifically focusing on printing the Unicode characters of pressed keys.
'
' It retrieves the current keymap using the xmodmap command, parses keycodes and
' their corresponding keysyms, and stores this information in structured data types.
'
' By tracking modifier states, the program accurately maps key events to their Unicode
' representations, allowing it to displau the correct characters and their names
' when keys are pressed.
'
' You can test this program after changing the keyboard language with setxkbmap.
'
' This program read raw keyboard events directly from a Linux input device file, typically
' located at `/dev/input/event0`. Modify keyboardFileName$ to change input device file.
'
' It is a low-level approach that bypasses standard input methods to capture every key
' press, release, and repeat event.
' ========================================================================================

' Structure to hold the current X11 keymap

type keymapType
    keycode as _unsigned _byte  ' xmodmap keycode adjusted (stored as keycode - 8)
    keysym2 as string            ' keysym for level 1 (no modifier)
    name2 as string              ' human-readable name for keysym2
    keysym3 as string            ' keysym for level 2 (Shift)
    name3 as string              ' human-readable name for keysym3
    keysym4 as string            ' keysym for level 3 (AltGr / Mode_switch)
    name4 as string              ' human-readable name for keysym4
    keysym5 as string            ' keysym for level 4 (Shift + AltGr)
    name5 as string              ' human-readable name for keysym5
end type

' Structure to hold a keysym definition parsed from keysymdef.h

type keysymdefType
    symname as string  ' The keysym name (e.g. "XK_A" without the "XK_" prefix in this code)
    symcode as string  ' The keysym constant value as found in the header (e.g. "0xff41")
    unicode as string  ' Optional Unicode mapping token (e.g. "U+0061") if present
end type

$console
_dest _console

' Execute the system command "xmodmap -pk" to get the current X11 keymap
' and extract keycodes, keysyms or names

shell "xmodmap -pk > ./keyboardWithXmodmap.tmp"
content$ = _readfile$("./keyboardWithXmodmap.tmp")
kill "./keyboardWithXmodmap.tmp"

redim xmodmap$(0)
split content$, _STR_NAT_EOL, xmodmap$()
clean xmodmap$()

dim keymap(8 to 255) as keymapType

for i%=3 to ubound(xmodmap$)
    replace xmodmap$(i%), chr$(9), chr$(32)
    redim keyCodeAndSym$(0)
    split xmodmap$(i%), " ", keyCodeAndSym$()
    k% = val(keyCodeAndSym$(0))
    keymap(k%).keycode = k% - 8
    if ubound(keyCodeAndSym$)>5 then
        keymap(k%).keysym2 = keyCodeAndSym$(5)
        keymap(k%).name2 = keyCodeAndSym$(6)
    end if
    if ubound(keyCodeAndSym$)>7 then
        keymap(k%).keysym3 = keyCodeAndSym$(7)
        keymap(k%).name3 = keyCodeAndSym$(8)
    end if
    if ubound(keyCodeAndSym$)>9 then
        keymap(k%).keysym4 = keyCodeAndSym$(9)
        keymap(k%).name4 = keyCodeAndSym$(10)
    end if
    if ubound(keyCodeAndSym$)>11 then
        keymap(k%).keysym5 = keyCodeAndSym$(11)
        keymap(k%).name5 = keyCodeAndSym$(12)
    end if
next i%

' Get X11 keysym definitions from /usr/include/X11/keysymdef.h into ks() array

dim ks(2200) as keysymdefType

l% = 1

open "/usr/include/X11/keysymdef.h" for input as #1

do while not eof(1)
    line input #1, content$
    redim r$(0)
    split content$, " ",  r$()
    if ubound(r$) = 0 then _continue
    if left$(r$(lbound(r$)),7) <> "#define" then _continue
    ks(l%).symname = mid$(r$(lbound(r$)+1),4)
    ks(l%).symcode = r$(lbound(r$)+2)
    for i% = lbound(r$)+3 to ubound(r$)
        if left$(r$(i%),2) = "U+" then ks(l%).unicode = r$(i%)
    next i%
    l% = l% + 1
loop

close #1

' Get Caps Lock status

shell "xset -q | sed -n 's/^.*Caps Lock:\s*\(\S*\).*$/\1/p' > ./keyboardWithXmodmap.tmp"
open "./keyboardWithXmodmap.tmp" for input as #1
line input #1, content$
close #1
kill "./keyboardWithXmodmap.tmp"

if _trim$(content$) = "off" then
    capsOn = 0
    modifiers = 0
    additionals = 0
else
    capsOn = 1
    modifiers = 256
    additionals = 256
end if

' main window

screen _NewImage(1024,768,32)

' load the first monospace font

shell "fc-list :spacing=100:style=bold:lang=fr | head -n 1 | cut -d: -f1 > ./keyboardWithXmodmap.tmp"
open "./keyboardWithXmodmap.tmp" for input as #1
line input #1, fontFile$
close #1
kill "./keyboardWithXmodmap.tmp"

DIM fh AS LONG:
fh = _loadfont(fontFile$,16)
IF fh <= 0 THEN
    $console
    _dest _console
    PRINT "Failed to load font file!"
    _dest 0
    END
END IF
_FONT fh

' Reads 24-byte event structures from the specified device file.
'
' It filters for key-related events and then determines if the event is a key press (DOWN_DETECTED),
' a key release (UP_DETECTED), or an auto-repeat (REPEAT_DETECTED).
'
' It specifically tracks the state of modifier keys (Left Shift, Right Shift, and Right Alt)
' to correctly interpret the character generated by other key presses.
'
' When a non-modifier key is pressed, it uses the key's scancode combined with the current state
' of the modifiers to look up the appropriate  keysym and character name from a `keymap` array (not defined in this snippet).
'
' The resulting information is then printed to the window.

const KEY_EVENT = &h01
const UP_DETECTED = 0
const DOWN_DETECTED = 1
const REPEAT_DETECTED = 2

' modifier keys
const KEY_LEFTSHIFT = 42
const KEY_RIGHTSHIFT = 54
const KEY_RIGHTALT = 100

' additional modifier keys
const KEY_LEFTALT = 56
const KEY_LEFTCONTROL = 29
const KEY_RIGHTCONTROL = 97
const KEY_LEFTSUPER = 125
const KEY_RIGHTSUPER = 126
const KEY_CAPITAL = 58

dim aByte(24) as _unsigned _byte

keyboardFileName$ = "/dev/input/event0"
open keyboardFileName$ for binary as #1

print "keycode", "keysym", "unicode", "char.", "name"
p% = 1
do
    get #1, , aByte(p%)
    if (p% MOD 24) = 0 then
        if aByte(17) = KEY_EVENT then
            select case aByte(21)
                case UP_DETECTED
                    select case aByte(19)
                        case KEY_LEFTSHIFT :
                            modifiers = modifiers and not 1
                            additionals = additionals and not 1
                        case KEY_RIGHTSHIFT :
                            modifiers = modifiers and not 1
                            additionals = additionals and not 2
                        case KEY_LEFTALT :
                            additionals = additionals and not 4
                        case KEY_RIGHTALT :
                            modifiers = modifiers and not 2
                            additionals = additionals and not 8
                        case KEY_LEFTCONTROL :
                            additionals = additionals and not 16
                        case KEY_RIGHTCONTROL :
                            additionals = additionals and not 32
                        case KEY_LEFTSUPER :
                            additionals = additionals and not 64
                        case KEY_RIGHTSUPER :
                            additionals = additionals and not 128
                    end select
                case DOWN_DETECTED
                    if aByte(19) = 1 then exit do    ' Exit on ESC key down
                    select case aByte(19)
                        case KEY_LEFTSHIFT :
                            modifiers = modifiers or 1
                            additionals = additionals or 1
                        case KEY_RIGHTSHIFT :
                            modifiers = modifiers or 1
                            additionals = additionals or 2
                        case KEY_LEFTALT :
                            additionals = additionals or 4
                        case KEY_RIGHTALT :
                            modifiers = modifiers or 2
                            additionals = additionals or 8
                        case KEY_LEFTCONTROL :
                            additionals = additionals or 16
                        case KEY_RIGHTCONTROL :
                            additionals = additionals or 32
                        case KEY_LEFTSUPER :
                            additionals = additionals or 64
                        case KEY_RIGHTSUPER :
                            additionals = additionals or 128
                        case KEY_CAPITAL :
                            capsOn = 1 - capsOn
                            if capsOn = 0 then
                                modifiers = modifiers and not 256
                                additionals = additionals and not 256
                            else
                                modifiers = modifiers or 256
                                additionals = additionals or 256
                            end if
                        case else:
                            k% = aByte(19)+8
                            baseKeysym$ = keymap(k%).keysym2
                            if modifiers = 0 then
                                keysym$ = keymap(k%).keysym2
                                name$ = keymap(k%).name2
                            elseif (modifiers and 256) > 0 then
                                if (modifiers and 1) > 0 then ' caps lock + shift = nocaps
                                    keysym$ = keymap(k%).keysym2
                                    name$ = keymap(k%).name2
                                else ' caps lock + no shift = caps
                                    keysym$ = keymap(k%).keysym3
                                    name$ = keymap(k%).name3
                                end if
                            elseif modifiers = 1 then ' shift alone
                                keysym$ = keymap(k%).keysym3
                                name$ = keymap(k%).name3
                            elseif modifiers = 2 then 'altgr
                                keysym$ = keymap(k%).keysym4
                                name$ = keymap(k%).name4
                            elseif modifiers = 3 then ' shift+ altgr
                                keysym$ = keymap(k%).keysym5
                                name$ = keymap(k%).name5
                            end if
                            additional$ = ""
                            if (additionals and 1) > 0 then additional$ = additional$ + "LShift + "
                            if (additionals and 2) > 0 then additional$ = additional$ + "RShift + "
                            if (additionals and 4) > 0 then additional$ = additional$ + "Alt + "
                            if (additionals and 8) > 0 then additional$ = additional$ + "AltGr + "
                            if (additionals and 16) > 0 then additional$ = additional$ + "LCtrl + "
                            if (additionals and 32) > 0 then additional$ = additional$ + "RCtrl + "
                            if (additionals and 64) > 0 then additional$ = additional$ + "LSuper + "
                            if (additionals and 128) > 0 then additional$ = additional$ + "RSuper + "
                            if (additionals and 256) > 0 then additional$ = "Caps Lock + " + additional$
                            printData keymap(k%).keycode, keysym$, name$, ks(), additional$, baseKeysym$
                    end select
                case REPEAT_DETECTED
                    if SHOW_ME_REPETITION then
                        print " REPEAT  ", aByte(19)
                    end if
            end select
        end if
        p% = 0
    end if
    p% = p% + 1
loop

system

sub printData (keycode, keysym as string, keyname as string, ks() as keysymdefType, ad as string, baseKeysym as string)
    if keysym = "" then
        _dest _console
        print keycode, space$(8), space$(8), space$(8), keyname
        _dest 0
        print keycode, space$(8), space$(8), space$(8), keyname
    end if
    base$ = Utf8FromCodepoint(val("&H"+mid$(_trim$(searchKeysym(ks(),baseKeysym)),3)))
    uc$ = _trim$(searchKeysym(ks(),keysym))
    unicode = val("&H"+mid$(uc$,3))
    if unicode > 0 then
        _mapunicode unicode to &HFF
        u$ = Utf8FromCodepoint(unicode)
        if ad <> "" then
            _dest _console
            print keycode, keysym, uc$, u$, keyname, ad; base$
            _dest 0
            print keycode, keysym, uc$, chr$(&HFF), keyname, ad; base$
        else
            _dest _console
            print keycode, keysym, uc$, u$, keyname
            _dest 0
            print keycode, keysym, uc$, chr$(&HFF), keyname
        end if
    else
        if ad <> "" then
            _dest _console
            print keycode, keysym, space$(8), space$(8), keyname, ad; base$
            _dest 0
            print keycode, keysym, space$(8), space$(8), keyname, ad; base$
        else
            _dest _console
            print keycode, keysym, space$(8), space$(8), keyname
            _dest 0
            print keycode, keysym, space$(8), space$(8), keyname
        end if
    end if
end sub

' print keycode, keysym, unicode, character, character name

sub printData2 (keycode, keysym as string, keyname as string, ks() as keysymdefType, ad as string)
    if keysym = "" then
        print keycode, space$(8), space$(8), space$(8), keyname
    end if
    uc$ = _trim$(searchKeysym(ks(),keysym))
    unicode = val("&H"+mid$(uc$,3))
    if unicode > 0 then
        _mapunicode unicode to &HFF
        if ad <> "" then
            print keycode, keysym, uc$, chr$(&HFF), keyname, ad ; chr$(&HFF)
        else
            print keycode, keysym, uc$, chr$(&HFF), keyname
        end if
    else
        if ad <> "" then
            print keycode, keysym, space$(8), space$(8), keyname, ad ; keyname
        else
            print keycode, keysym, space$(8), space$(8), keyname
        end if
    end if
end sub

' search keysym to get the unicode equivalent

function searchKeysym$ (ks() as keysymdefType, keysym as string)
    res$ = ""
    for i% = lbound(ks) to ubound(ks)
        if ks(i%).symcode = keysym then
            res$ = ks(i%).unicode
            exit for
        end if
    next i%
    searchKeysym = res$
end function

' split string using a delimiter

Sub split (in$, delimiter$, result$())
    ReDim result$(-1)
    dim start, finish
    start = 1
    Do
        While Mid$(in$, start, 1) = delimiter$
            start = start + 1
            If start > Len(in$) Then Exit Sub
        Wend
        finish = InStr(start, in$, delimiter$)
        If finish = 0 Then finish = Len(in$) + 1
        ReDim _Preserve result$(0 To UBound(result$) + 1)
        result$(UBound(result$)) = Mid$(in$, start, finish - start)
        start = finish + 1
    Loop While start <= Len(in$)
End Sub

' clean array of string

sub clean (result$())
    dim i%
    for i% = lbound(result$) to ubound(result$)
        if right$(result$(i%),1) = chr$(13) then
            result$(i%) = left$(result$(i%),len(result$(i%))-1)
        end if 
    next i%
end sub

' replace findString with replaceString into myString

sub replace (myString$, findString$, replaceString$)
    start% = 1
    do
        position% = INSTR(start%, myString$, findString$)
        IF position% THEN
            MID$(myString$, position%, len(findString$)) = replaceString$
            start% = position% + 1
        END IF
    loop until position% = 0
end sub

function Utf8FromCodepoint$ (cp as _unsigned LONG)
    if cp <= &H7F then
        Utf8FromCodepoint$ = chr$(cp)
    elseif cp <= &H7FF then
        Utf8FromCodepoint$ = chr$(&HC0 or _shr(cp,6)) _
                          + chr$(&H80 or (cp and &H3F))
    elseif cp <= &HFFFF then
        Utf8FromCodepoint$ = chr$(&HE0 or _shr(cp,12)) _
                          + chr$(&H80 or (_shr(cp,6) and &H3F)) _
                          + chr$(&H80 or (cp and &H3F))
    else
        Utf8FromCodepoint$ = chr$(&HF0 or _shr(cp,18)) _
                          + chr$(&H80 or (_shr(cp,12) and &H3F)) _
                          + chr$(&H80 or (_shr(cp,6) and &H3F)) _
                          + chr$(&H80 or (cp and &H3F))
    end if
end function
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Tab() special behaviour in Console? zaadstra 17 1,256 12-06-2025, 02:08 PM
Last Post: bplus
  performance drop on LINUX with PSET in v4.2 Herve 12 943 11-20-2025, 02:00 PM
Last Post: SpriggsySpriggs
  sending MIDI notes to/from QB64PE to a real MIDI keyboard plugged into the PC? madscijr 5 1,043 03-12-2025, 03:36 AM
Last Post: madscijr
  OpenGL Lighting Issue aadityap0901 11 1,978 10-02-2024, 12:57 PM
Last Post: aadityap0901
  How to find Default Web Browser in Linux ? ahenry3068 3 883 09-20-2024, 01:51 PM
Last Post: ahenry3068

Forum Jump:


Users browsing this thread: