Added untested advanced keycode translation
This commit is contained in:
		
							parent
							
								
									820c7d4f6a
								
							
						
					
					
						commit
						84cd21b16d
					
				| @ -58,8 +58,8 @@ func (backend *Backend) handleKeyPress ( | ||||
| 	event xevent.KeyPressEvent, | ||||
| ) { | ||||
| 	keyEvent := *event.KeyPressEvent | ||||
| 	keysym   := backend.keycodeToKeysym(keyEvent.Detail) | ||||
| 	backend.channel <- stone.EventPress(keysymToButtonCode(keysym)) | ||||
| 	button   := backend.keycodeToButton(keyEvent.Detail, keyEvent.State) | ||||
| 	backend.channel <- stone.EventPress(button) | ||||
| } | ||||
| 
 | ||||
| func (backend *Backend) handleKeyRelease ( | ||||
| @ -67,8 +67,8 @@ func (backend *Backend) handleKeyRelease ( | ||||
| 	event xevent.KeyReleaseEvent, | ||||
| ) { | ||||
| 	keyEvent := *event.KeyReleaseEvent | ||||
| 	keysym   := backend.keycodeToKeysym(keyEvent.Detail) | ||||
| 	backend.channel <- stone.EventRelease(keysymToButtonCode(keysym)) | ||||
| 	button   := backend.keycodeToButton(keyEvent.Detail, keyEvent.State) | ||||
| 	backend.channel <- stone.EventRelease(button) | ||||
| } | ||||
| 
 | ||||
| func (backend *Backend) handleMotionNotify ( | ||||
|  | ||||
| @ -1,5 +1,6 @@ | ||||
| package x | ||||
| 
 | ||||
| import "unicode" | ||||
| import "github.com/jezek/xgb/xproto" | ||||
| import "github.com/jezek/xgbutil/keybind" | ||||
| import "git.tebibyte.media/sashakoshka/stone" | ||||
| @ -55,48 +56,138 @@ var buttonCodeTable = map[xproto.Keysym] stone.Button { | ||||
| 	0xFFC9: stone.KeyF12, | ||||
| } | ||||
| 
 | ||||
| func (backend *Backend) keycodeToKeysym ( | ||||
| func (backend *Backend) keycodeToButton ( | ||||
| 	keycode xproto.Keycode, | ||||
| 	state   uint16, | ||||
| ) ( | ||||
| 	keysym xproto.Keysym, | ||||
| 	button stone.Button, | ||||
| ) { | ||||
| 	keysym = keybind.KeysymGet(backend.connection, keycode, 0) | ||||
| 	// 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 | ||||
| 
 | ||||
| 	symbol1 := keybind.KeysymGet(backend.connection, keycode, 0) | ||||
| 	symbol2 := keybind.KeysymGet(backend.connection, keycode, 1) | ||||
| 	symbol3 := keybind.KeysymGet(backend.connection, keycode, 2) | ||||
| 	symbol4 := keybind.KeysymGet(backend.connection, keycode, 3) | ||||
| 
 | ||||
| 	cased := false | ||||
| 
 | ||||
| 	// third paragraph | ||||
| 	switch { | ||||
| 	case symbol2 == 0 && symbol3 == 0 && symbol4 == 0: | ||||
| 		symbol3 = symbol1 | ||||
| 	case symbol3 == 0 && symbol4 == 0: | ||||
| 		symbol3 = symbol1 | ||||
| 		symbol2 = symbol2 | ||||
| 	case symbol4 == 0: | ||||
| 		symbol4 = 0 | ||||
| 	} | ||||
| 
 | ||||
| 	symbol1Rune := keysymToRune(symbol1) | ||||
| 	symbol2Rune := keysymToRune(symbol2) | ||||
| 	symbol3Rune := keysymToRune(symbol3) | ||||
| 	symbol4Rune := keysymToRune(symbol4) | ||||
| 
 | ||||
| 	// FIXME: we ignore mode switch stuff | ||||
| 	_ = symbol4Rune | ||||
| 
 | ||||
| 	// fourth paragraph | ||||
| 	if symbol2 == 0 { | ||||
| 		upper := unicode.IsUpper(symbol1Rune) | ||||
| 		lower := unicode.IsLower(symbol1Rune) | ||||
| 		if upper || lower { | ||||
| 			symbol1Rune = unicode.ToLower(symbol1Rune) | ||||
| 			symbol2Rune = unicode.ToUpper(symbol1Rune) | ||||
| 			cased = true | ||||
| 		} else { | ||||
| 			symbol2 = symbol1 | ||||
| 		} | ||||
| 	} | ||||
| 	if symbol4 == 0 { | ||||
| 		upper := unicode.IsUpper(symbol3Rune) | ||||
| 		lower := unicode.IsLower(symbol3Rune) | ||||
| 		if upper || lower { | ||||
| 			symbol3Rune = unicode.ToLower(symbol3Rune) | ||||
| 			symbol4Rune = unicode.ToUpper(symbol3Rune) | ||||
| 			cased = true | ||||
| 		} else { | ||||
| 			symbol4 = symbol3 | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	var selectedKeysym xproto.Keysym | ||||
| 	var selectedRune   rune | ||||
| 	 | ||||
| 	// big ol list in the middle | ||||
| 	switch { | ||||
| 	// FIXME: take into account numlock | ||||
| 	case !shift && !capsLock: | ||||
| 		selectedKeysym = symbol1 | ||||
| 		selectedRune   = symbol1Rune | ||||
| 		 | ||||
| 	case !shift && capsLock: | ||||
| 		if cased && unicode.IsLower(symbol1Rune) { | ||||
| 			selectedRune = symbol2Rune | ||||
| 		} else { | ||||
| 			selectedKeysym = symbol1 | ||||
| 			selectedRune   = symbol1Rune | ||||
| 		} | ||||
| 		 | ||||
| 	case shift && capsLock: | ||||
| 		if cased && unicode.IsLower(symbol2Rune) { | ||||
| 			selectedRune = unicode.ToUpper(symbol2Rune) | ||||
| 		} else { | ||||
| 			selectedKeysym = symbol2 | ||||
| 			selectedRune   = symbol2Rune | ||||
| 		} | ||||
| 		 | ||||
| 	case shift: | ||||
| 		selectedKeysym = symbol3 | ||||
| 		selectedRune   = symbol3Rune | ||||
| 	} | ||||
| 
 | ||||
| 	// look up in table | ||||
| 	var isControl bool | ||||
| 	button, isControl = buttonCodeTable[selectedKeysym] | ||||
| 	if isControl { return } | ||||
| 
 | ||||
| 	button = stone.Button(selectedRune) | ||||
| 
 | ||||
| 	// TODO: shift isnt working. follow | ||||
| 	// https://tronche.com/gui/x/xlib/input/keyboard-encoding.html | ||||
| 	 | ||||
| 	println("--") | ||||
| 	println(keycode) | ||||
| 	println(keysym) | ||||
| 	println(stone.EventPress(keysymToButtonCode(keysym))) | ||||
| 	println(selectedKeysym) | ||||
| 	println(selectedRune) | ||||
| 	println(button) | ||||
| 	 | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| func keysymToButtonCode (keysym xproto.Keysym) (button stone.Button) { | ||||
| 	var isControl bool | ||||
| 	button, isControl = buttonCodeTable[keysym] | ||||
| 	if isControl { return } | ||||
| func keysymToRune (keysym xproto.Keysym) (character rune) { | ||||
| 	// X keysyms like 0xFF.. or 0xFE.. are non-character keys. these cannot | ||||
| 	// be converted so we return a zero. | ||||
| 	if (keysym >> 8) == 0xFF || (keysym >> 8) == 0xFE { | ||||
| 		character = 0 | ||||
| 		return | ||||
| 	} | ||||
| 	 | ||||
| 	// some X keysyms have a single bit set to 1 here. i believe this is to | ||||
| 	// prevent conflicts with existing codes. if we mask it off we will get | ||||
| 	// a correct utf-32 code point. | ||||
| 	if keysym & 0xF000000 == 0x1000000 { | ||||
| 		button = stone.Button(keysym & 0x0111111) | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| 	// X keysyms like 0xFF.. or 0xFE.. are non-character keys. we already | ||||
| 	// resolve these by looking them up in the button code table, so if any | ||||
| 	// that we don't support pop up we should just silence them as it is | ||||
| 	// effectively garbage data as far as stone applications are concerned. | ||||
| 	if (keysym >> 8) == 0xFF || (keysym >> 8) == 0xFE { | ||||
| 		button = stone.ButtonUnknown | ||||
| 		character = rune(keysym & 0x0111111) | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| 	// if none of these things happened, we can safely (i think) assume that | ||||
| 	// the keysym is an exact utf-32 code point. | ||||
| 	button = stone.Button(keysym) | ||||
| 	character = rune(keysym) | ||||
| 	return | ||||
| } | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user