gosmartkeyboard/docs/Client.html

194 lines
6.6 KiB
HTML
Raw Permalink Normal View History

2023-03-07 22:29:26 +00:00
<!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 &ldquo;authenticated&rdquo;, 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) &gt; 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(&amp;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) &gt; 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(&amp;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>