THE DRAGON HAS BEEN SLAIN
Numlock is fully supported, as well as shift lock. Of course, I cannot properly test shift lock or caps lock because I have neither of those things, but I assume they work as well as num lock does.
This commit is contained in:
parent
33ed2af075
commit
941a78eaf1
@ -74,7 +74,13 @@ func factory (
|
||||
if err != nil { return }
|
||||
backend.window, err = xwindow.Generate(backend.connection)
|
||||
if err != nil { return }
|
||||
|
||||
// get keyboard mapping information
|
||||
keybind.Initialize(backend.connection)
|
||||
backend.modifierMasks.capsLock = backend.keysymToMask(0xFFE5)
|
||||
backend.modifierMasks.shiftLock = backend.keysymToMask(0xFFE6)
|
||||
backend.modifierMasks.numLock = backend.keysymToMask(0xFF7F)
|
||||
backend.modifierMasks.modeSwitch = backend.keysymToMask(0xFF7E)
|
||||
|
||||
// create the window
|
||||
backend.window.Create (
|
||||
@ -158,6 +164,38 @@ func findAndLoadFont (name string, size float64) (face font.Face) {
|
||||
return
|
||||
}
|
||||
|
||||
func (backend *Backend) keysymToKeycode (
|
||||
symbol xproto.Keysym,
|
||||
) (
|
||||
code xproto.Keycode,
|
||||
) {
|
||||
mapping := keybind.KeyMapGet(backend.connection)
|
||||
|
||||
for index, testSymbol := range mapping.Keysyms {
|
||||
if testSymbol == symbol {
|
||||
code = xproto.Keycode (
|
||||
index /
|
||||
int(mapping.KeysymsPerKeycode) +
|
||||
int(backend.connection.Setup().MinKeycode))
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (backend *Backend) keysymToMask (
|
||||
symbol xproto.Keysym,
|
||||
) (
|
||||
mask uint16,
|
||||
) {
|
||||
mask = keybind.ModGet (
|
||||
backend.connection,
|
||||
backend.keysymToKeycode(symbol))
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// init registers this backend when the program starts.
|
||||
func init () {
|
||||
stone.RegisterBackend(factory)
|
||||
|
@ -1,5 +1,7 @@
|
||||
package x
|
||||
|
||||
// TODO: rename this file? lol
|
||||
|
||||
// import "fmt"
|
||||
import "unicode"
|
||||
import "github.com/jezek/xgb/xproto"
|
||||
@ -117,13 +119,11 @@ func (backend *Backend) keycodeToButton (
|
||||
button stone.Button,
|
||||
numberPad bool,
|
||||
) {
|
||||
// FIXME: also set shift to true if the lock modifier is on and the lock
|
||||
// modifier is interpreted as shiftLock
|
||||
shift := state & xproto.ModMaskShift > 0
|
||||
|
||||
// FIXME: only set this to true if the lock modifier is on and the lock
|
||||
// modifier is interpreted as capsLock
|
||||
capsLock := state & xproto.ModMaskLock > 0
|
||||
shift :=
|
||||
state & xproto.ModMaskShift > 0 ||
|
||||
state & backend.modifierMasks.shiftLock > 0
|
||||
capsLock := state & backend.modifierMasks.capsLock > 0
|
||||
numLock := state & backend.modifierMasks.numLock > 0
|
||||
|
||||
symbol1 := keybind.KeysymGet(backend.connection, keycode, 0)
|
||||
symbol2 := keybind.KeysymGet(backend.connection, keycode, 1)
|
||||
@ -132,7 +132,19 @@ func (backend *Backend) keycodeToButton (
|
||||
|
||||
cased := false
|
||||
|
||||
// third paragraph
|
||||
// PARAGRAPH 3
|
||||
//
|
||||
// A list of KeySyms is associated with each KeyCode. The list is
|
||||
// intended to convey the set of symbols on the corresponding key. If
|
||||
// the list (ignoring trailing NoSymbol entries) is a single KeySym
|
||||
// ``K'', then the list is treated as if it were the list ``K NoSymbol
|
||||
// K NoSymbol''. If the list (ignoring trailing NoSymbol entries) is a
|
||||
// pair of KeySyms ``K1 K2'', then the list is treated as if it were the
|
||||
// list ``K1 K2 K1 K2''. If the list (ignoring trailing NoSymbol
|
||||
// entries) is a triple of KeySyms ``K1 K2 K3'', then the list is
|
||||
// treated as if it were the list ``K1 K2 K3 NoSymbol''. When an
|
||||
// explicit ``void'' element is desired in the list, the value
|
||||
// VoidSymbol can be used.
|
||||
switch {
|
||||
case symbol2 == 0 && symbol3 == 0 && symbol4 == 0:
|
||||
symbol3 = symbol1
|
||||
@ -151,7 +163,18 @@ func (backend *Backend) keycodeToButton (
|
||||
// FIXME: we ignore mode switch stuff
|
||||
_ = symbol4Rune
|
||||
|
||||
// fourth paragraph
|
||||
// PARAGRAPH 4
|
||||
//
|
||||
// The first four elements of the list are split into two groups of
|
||||
// KeySyms. Group 1 contains the first and second KeySyms; Group 2
|
||||
// contains the third and fourth KeySyms. Within each group, if the
|
||||
// second element of the group is NoSymbol , then the group should be
|
||||
// treated as if the second element were the same as the first element,
|
||||
// except when the first element is an alphabetic KeySym ``K'' for which
|
||||
// both lowercase and uppercase forms are defined. In that case, the
|
||||
// group should be treated as if the first element were the lowercase
|
||||
// form of ``K'' and the second element were the uppercase form of
|
||||
// ``K.''
|
||||
if symbol2 == 0 {
|
||||
upper := unicode.IsUpper(symbol1Rune)
|
||||
lower := unicode.IsLower(symbol1Rune)
|
||||
@ -180,14 +203,37 @@ func (backend *Backend) keycodeToButton (
|
||||
var selectedKeysym xproto.Keysym
|
||||
var selectedRune rune
|
||||
|
||||
// big ol list in the middle
|
||||
_, symbol2IsNumPad := keypadCodeTable[symbol2]
|
||||
|
||||
// "PARAGRAPH" 5
|
||||
//
|
||||
// Within a group, the choice of KeySym is determined by applying the
|
||||
// first rule that is satisfied from the following list:
|
||||
switch {
|
||||
// FIXME: take into account numlock
|
||||
case numLock && symbol2IsNumPad:
|
||||
// The numlock modifier is on and the second KeySym is a keypad
|
||||
// KeySym. In this case, if the Shift modifier is on, or if the
|
||||
// Lock modifier is on and is interpreted as ShiftLock, then the
|
||||
// first KeySym is used, otherwise the second KeySym is used.
|
||||
if shift {
|
||||
selectedKeysym = symbol1
|
||||
selectedRune = symbol1Rune
|
||||
} else {
|
||||
selectedKeysym = symbol2
|
||||
selectedRune = symbol2Rune
|
||||
}
|
||||
|
||||
case !shift && !capsLock:
|
||||
// The Shift and Lock modifiers are both off. In this case, the
|
||||
// first KeySym is used.
|
||||
selectedKeysym = symbol1
|
||||
selectedRune = symbol1Rune
|
||||
|
||||
case !shift && capsLock:
|
||||
// The Shift modifier is off, and the Lock modifier is on and is
|
||||
// interpreted as CapsLock. In this case, the first KeySym is
|
||||
// used, but if that KeySym is lowercase alphabetic, then the
|
||||
// corresponding uppercase KeySym is used instead.
|
||||
if cased && unicode.IsLower(symbol1Rune) {
|
||||
selectedRune = symbol2Rune
|
||||
} else {
|
||||
@ -196,6 +242,10 @@ func (backend *Backend) keycodeToButton (
|
||||
}
|
||||
|
||||
case shift && capsLock:
|
||||
// The Shift modifier is on, and the Lock modifier is on and is
|
||||
// interpreted as CapsLock. In this case, the second KeySym is
|
||||
// used, but if that KeySym is lowercase alphabetic, then the
|
||||
// corresponding uppercase KeySym is used instead.
|
||||
if cased && unicode.IsLower(symbol2Rune) {
|
||||
selectedRune = unicode.ToUpper(symbol2Rune)
|
||||
} else {
|
||||
@ -204,6 +254,9 @@ func (backend *Backend) keycodeToButton (
|
||||
}
|
||||
|
||||
case shift:
|
||||
// The Shift modifier is on, or the Lock modifier is on and is
|
||||
// interpreted as ShiftLock, or both. In this case, the second
|
||||
// KeySym is used.
|
||||
selectedKeysym = symbol2
|
||||
selectedRune = symbol2Rune
|
||||
}
|
||||
|
@ -43,6 +43,13 @@ type Backend struct {
|
||||
descent int
|
||||
}
|
||||
|
||||
modifierMasks struct {
|
||||
capsLock uint16
|
||||
shiftLock uint16
|
||||
numLock uint16
|
||||
modeSwitch uint16
|
||||
}
|
||||
|
||||
windowBoundsClean bool
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user