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 } | 	if err != nil { return } | ||||||
| 	backend.window, err = xwindow.Generate(backend.connection) | 	backend.window, err = xwindow.Generate(backend.connection) | ||||||
| 	if err != nil { return } | 	if err != nil { return } | ||||||
|  | 
 | ||||||
|  | 	// get keyboard mapping information | ||||||
| 	keybind.Initialize(backend.connection) | 	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 | 	// create the window | ||||||
| 	backend.window.Create ( | 	backend.window.Create ( | ||||||
| @ -158,6 +164,38 @@ func findAndLoadFont (name string, size float64) (face font.Face) { | |||||||
| 	return | 	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. | // init registers this backend when the program starts. | ||||||
| func init () { | func init () { | ||||||
| 	stone.RegisterBackend(factory) | 	stone.RegisterBackend(factory) | ||||||
|  | |||||||
| @ -1,5 +1,7 @@ | |||||||
| package x | package x | ||||||
| 
 | 
 | ||||||
|  | // TODO: rename this file? lol | ||||||
|  | 
 | ||||||
| // import "fmt" | // import "fmt" | ||||||
| import "unicode" | import "unicode" | ||||||
| import "github.com/jezek/xgb/xproto" | import "github.com/jezek/xgb/xproto" | ||||||
| @ -117,13 +119,11 @@ func (backend *Backend) keycodeToButton ( | |||||||
| 	button    stone.Button, | 	button    stone.Button, | ||||||
| 	numberPad bool, | 	numberPad bool, | ||||||
| ) { | ) { | ||||||
| 	// FIXME: also set shift to true if the lock modifier is on and the lock | 	shift := | ||||||
| 	// modifier is interpreted as shiftLock | 		state & xproto.ModMaskShift             > 0 || | ||||||
| 	shift    := state & xproto.ModMaskShift > 0 | 		state & backend.modifierMasks.shiftLock > 0 | ||||||
| 
 | 	capsLock := state & backend.modifierMasks.capsLock  > 0 | ||||||
| 	// FIXME: only set this to true if the lock modifier is on and the lock | 	numLock  := state & backend.modifierMasks.numLock   > 0 | ||||||
| 	// modifier is interpreted as capsLock |  | ||||||
| 	capsLock := state & xproto.ModMaskLock  > 0 |  | ||||||
| 
 | 
 | ||||||
| 	symbol1 := keybind.KeysymGet(backend.connection, keycode, 0) | 	symbol1 := keybind.KeysymGet(backend.connection, keycode, 0) | ||||||
| 	symbol2 := keybind.KeysymGet(backend.connection, keycode, 1) | 	symbol2 := keybind.KeysymGet(backend.connection, keycode, 1) | ||||||
| @ -132,7 +132,19 @@ func (backend *Backend) keycodeToButton ( | |||||||
| 
 | 
 | ||||||
| 	cased := false | 	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 { | 	switch { | ||||||
| 	case symbol2 == 0 && symbol3 == 0 && symbol4 == 0: | 	case symbol2 == 0 && symbol3 == 0 && symbol4 == 0: | ||||||
| 		symbol3 = symbol1 | 		symbol3 = symbol1 | ||||||
| @ -151,7 +163,18 @@ func (backend *Backend) keycodeToButton ( | |||||||
| 	// FIXME: we ignore mode switch stuff | 	// FIXME: we ignore mode switch stuff | ||||||
| 	_ = symbol4Rune | 	_ = 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 { | 	if symbol2 == 0 { | ||||||
| 		upper := unicode.IsUpper(symbol1Rune) | 		upper := unicode.IsUpper(symbol1Rune) | ||||||
| 		lower := unicode.IsLower(symbol1Rune) | 		lower := unicode.IsLower(symbol1Rune) | ||||||
| @ -180,30 +203,60 @@ func (backend *Backend) keycodeToButton ( | |||||||
| 	var selectedKeysym xproto.Keysym | 	var selectedKeysym xproto.Keysym | ||||||
| 	var selectedRune   rune | 	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 { | 	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: | 	case !shift && !capsLock: | ||||||
|  | 		// The Shift and Lock modifiers are both off. In this case, the | ||||||
|  | 		// first KeySym is used. | ||||||
| 		selectedKeysym = symbol1 | 		selectedKeysym = symbol1 | ||||||
| 		selectedRune   = symbol1Rune | 		selectedRune   = symbol1Rune | ||||||
| 		 | 
 | ||||||
| 	case !shift && capsLock: | 	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) { | 		if cased && unicode.IsLower(symbol1Rune) { | ||||||
| 			selectedRune = symbol2Rune | 			selectedRune = symbol2Rune | ||||||
| 		} else { | 		} else { | ||||||
| 			selectedKeysym = symbol1 | 			selectedKeysym = symbol1 | ||||||
| 			selectedRune   = symbol1Rune | 			selectedRune   = symbol1Rune | ||||||
| 		} | 		} | ||||||
| 		 | 
 | ||||||
| 	case shift && capsLock: | 	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) { | 		if cased && unicode.IsLower(symbol2Rune) { | ||||||
| 			selectedRune = unicode.ToUpper(symbol2Rune) | 			selectedRune = unicode.ToUpper(symbol2Rune) | ||||||
| 		} else { | 		} else { | ||||||
| 			selectedKeysym = symbol2 | 			selectedKeysym = symbol2 | ||||||
| 			selectedRune   = symbol2Rune | 			selectedRune   = symbol2Rune | ||||||
| 		} | 		} | ||||||
| 		 | 
 | ||||||
| 	case shift: | 	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 | 		selectedKeysym = symbol2 | ||||||
| 		selectedRune   = symbol2Rune | 		selectedRune   = symbol2Rune | ||||||
| 	} | 	} | ||||||
|  | |||||||
| @ -43,6 +43,13 @@ type Backend struct { | |||||||
| 		descent      int | 		descent      int | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	modifierMasks struct { | ||||||
|  | 		capsLock   uint16 | ||||||
|  | 		shiftLock  uint16 | ||||||
|  | 		numLock    uint16 | ||||||
|  | 		modeSwitch uint16 | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	windowBoundsClean bool | 	windowBoundsClean bool | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user