194 lines
6.6 KiB
HTML
194 lines
6.6 KiB
HTML
|
<!DOCTYPE html>
|
||
|
<html lang="en">
|
||
|
<head>
|
||
|
<meta charset="utf-8">
|
||
|
<meta name="viewport" content="width=device-width">
|
||
|
<title>GoSmartKeyboard</title>
|
||
|
<link rel="stylesheet" href="google-code-prettify/prettify.css">
|
||
|
<link rel="stylesheet" href="styles/prettify-theme.css">
|
||
|
<script defer src="google-code-prettify/prettify.js"></script>
|
||
|
<script defer src="google-code-prettify/run_prettify.js"></script>
|
||
|
<link rel="stylesheet" href="styles/main.css">
|
||
|
</head>
|
||
|
|
||
|
<!-- Generated by srcweave https://github.com/justinmeiners/srcweave -->
|
||
|
<h1>GoSmartKeyboard Client<a id="c20"></a></h1>
|
||
|
|
||
|
|
||
|
<p>When the GoSmartKeyboard client is started, it does the following:</p>
|
||
|
|
||
|
<ol>
|
||
|
<li>Load the connection URL from the first CLI argument.</li>
|
||
|
<li>Load the auth token from the environment variable <code>KEYBOARD_AUTH</code> or stdin if it does not exist.</li>
|
||
|
<li>Connect to the server.
|
||
|
4 Send the auth token to the server.</li>
|
||
|
<li>If the server responds with “authenticated”, we start reading keys from stdin and sending them to the server until EOF.</li>
|
||
|
<li>If KEYBOARD_FIFO is specified as an environment variable, we read from the path specified there instead as a named pipe.</li>
|
||
|
</ol>
|
||
|
|
||
|
|
||
|
|
||
|
<div class="code-block">
|
||
|
<span class="block-header">
|
||
|
<strong class="block-title"><em><a id="handle-client-command-block-67" href="#handle-client-command-block-67">handle client command</a></em></strong></span>
|
||
|
<pre class="prettyprint"><code class="">if len(os.Args) > 1 {
|
||
|
<em class="block-link nocode" title="EnvironmentVariables.html"><a href="EnvironmentVariables.html#get-client-fifo-input-file-from-environment-block-20">@{get client fifo input file from environment}</a></em>
|
||
|
<em class="block-link nocode"><a href="#setup-client-block-69">@{setup client}</a></em>
|
||
|
if clientFifoInputFileEnvExists {
|
||
|
<em class="block-link nocode"><a href="#start-client-with-fifo-block-73">@{start client with fifo}</a></em>
|
||
|
os.Exit(0)
|
||
|
}
|
||
|
<em class="block-link nocode"><a href="#start-client-with-stdin-block-75">@{start client with stdin}</a></em>
|
||
|
os.Exit(0)
|
||
|
}
|
||
|
</code></pre>
|
||
|
<p class="block-usages"><small>Used by <a href="#-client-main-client.go-block-79" title="/client/main-client.go">1</a> </small></p></div>
|
||
|
|
||
|
|
||
|
|
||
|
<h2>1. Connecting<a id="s20:0"></a></h2>
|
||
|
|
||
|
|
||
|
<p>The base64 authentication token is loaded from the environment variable <code>KEYBOARD_AUTH</code>, if it does not exist we read it from stdin (base64 encoded), ended with a newline.</p>
|
||
|
|
||
|
|
||
|
<div class="code-block">
|
||
|
<span class="block-header">
|
||
|
<strong class="block-title"><em><a id="setup-client-block-69" href="#setup-client-block-69">setup client</a></em></strong></span>
|
||
|
<pre class="prettyprint"><code class=""><em class="block-link nocode">@{load connection URL from second CLI argument}</em>
|
||
|
<em class="block-link nocode" title="EnvironmentVariables.html"><a href="EnvironmentVariables.html#get-authtokeninput-from-environment-block-18">@{get authTokenInput from environment}</a></em>
|
||
|
<em class="block-link nocode">@{add xdotool if non qwerty function}</em>
|
||
|
|
||
|
if !authTokenInputExists {
|
||
|
fmt.Print("Enter authentication token: ")
|
||
|
_, err := fmt.Scanln(&authTokenInput)
|
||
|
if err != nil {
|
||
|
log.Fatal(err)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
client, _, err := websocket.DefaultDialer.Dial(connectionURL, nil)
|
||
|
if err != nil {
|
||
|
log.Fatal("dial:", err)
|
||
|
}
|
||
|
defer client.Close()
|
||
|
|
||
|
err = client.WriteMessage(websocket.TextMessage, []byte(authTokenInput))
|
||
|
|
||
|
if err != nil {
|
||
|
log.Fatal("write:", err)
|
||
|
}
|
||
|
|
||
|
_, authResponse, err := client.ReadMessage()
|
||
|
if err != nil {
|
||
|
log.Fatal("read:", err)
|
||
|
}
|
||
|
if string(authResponse) == "authenticated" {
|
||
|
fmt.Println("authenticated")
|
||
|
} else {
|
||
|
log.Fatal("authentication failed")
|
||
|
}
|
||
|
</code></pre>
|
||
|
<p class="block-usages"><small>Used by <a href="#handle-client-command-block-67" title="handle client command">1</a> </small></p></div>
|
||
|
|
||
|
|
||
|
|
||
|
<h2>2. Sending keys from a named pipe<a id="s20:1"></a></h2>
|
||
|
|
||
|
|
||
|
|
||
|
<div class="code-block">
|
||
|
<span class="block-header">
|
||
|
<strong class="block-title"><em><a id="start-client-with-fifo-block-73" href="#start-client-with-fifo-block-73">start client with fifo</a></em></strong></span>
|
||
|
<pre class="prettyprint"><code class="">var inputString string
|
||
|
|
||
|
syscall.Mkfifo(clientFifoInputFile, syscall.S_IFIFO|0666)
|
||
|
|
||
|
for {
|
||
|
input, err := ioutil.ReadFile(clientFifoInputFile)
|
||
|
if err != nil {
|
||
|
log.Fatal(err)
|
||
|
}
|
||
|
inputString = addXDoToolIfNonQWERTY(string(input))
|
||
|
input = []byte(inputString)
|
||
|
if len(input) > 0 {
|
||
|
fmt.Println("send" + strings.Replace(string(input), " ", "space", 10))
|
||
|
err = client.WriteMessage(websocket.TextMessage, input)
|
||
|
if err != nil {
|
||
|
log.Fatal("write:", err)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
}
|
||
|
</code></pre>
|
||
|
<p class="block-usages"><small>Used by <a href="#handle-client-command-block-67" title="handle client command">1</a> </small></p></div>
|
||
|
|
||
|
|
||
|
|
||
|
<h2>3. Sending keys from stdin<a id="s20:2"></a></h2>
|
||
|
|
||
|
|
||
|
<p>We read keys from stdin and send them to the server until we get EOF.</p>
|
||
|
|
||
|
<p>We specify xdotool if the key is not a QWERTY key or if KEYBOARD_ALWAYS_XDOTOOL is set to true.</p>
|
||
|
|
||
|
|
||
|
<div class="code-block">
|
||
|
<span class="block-header">
|
||
|
<strong class="block-title"><em><a id="start-client-with-stdin-block-75" href="#start-client-with-stdin-block-75">start client with stdin</a></em></strong></span>
|
||
|
<pre class="prettyprint"><code class="">reader := bufio.NewReader(os.Stdin)
|
||
|
for {
|
||
|
var key string
|
||
|
|
||
|
|
||
|
rune, _, err := reader.ReadRune() //:= fmt.Scan(&key)
|
||
|
key = addXDoToolIfNonQWERTY(string(rune))
|
||
|
|
||
|
if err != nil {
|
||
|
if err == io.EOF {
|
||
|
break
|
||
|
}
|
||
|
log.Fatal(err)
|
||
|
}
|
||
|
fmt.Println("send" + strings.Replace(key, " ", "space", 10))
|
||
|
err = client.WriteMessage(websocket.TextMessage, []byte(key))
|
||
|
if err != nil {
|
||
|
log.Fatal("write:", err)
|
||
|
}
|
||
|
}
|
||
|
</code></pre>
|
||
|
<p class="block-usages"><small>Used by <a href="#handle-client-command-block-67" title="handle client command">1</a> </small></p></div>
|
||
|
|
||
|
|
||
|
|
||
|
<h1>Handling unicode outside of the ASCII set<a id="c21"></a></h1>
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
<div class="code-block">
|
||
|
<span class="block-header">
|
||
|
<strong class="block-title"><em><a id="-client-main-client.go-block-79" href="#-client-main-client.go-block-79">/client/main-client.go</a></em></strong></span>
|
||
|
<pre class="prettyprint"><code class="">package main
|
||
|
import (
|
||
|
"strings"
|
||
|
"io/ioutil"
|
||
|
"syscall"
|
||
|
"io"
|
||
|
"bufio"
|
||
|
"log"
|
||
|
"fmt"
|
||
|
"os"
|
||
|
<em class="block-link nocode" title="Dependencies.html"><a href="Dependencies.html#gorilla-websocket-import-string-block-11">@{gorilla/websocket import string}</a></em>
|
||
|
|
||
|
)
|
||
|
|
||
|
func main(){<em class="block-link nocode"><a href="#handle-client-command-block-67">@{handle client command}</a></em>}
|
||
|
</code></pre>
|
||
|
</div>
|
||
|
|
||
|
|
||
|
</body>
|
||
|
</html>
|