Good afternoon, friends, I want to immediately speak: this article by my friend, who wanted to publish it, but by mistake sent it to the sandbox that was not completed, and could no longer lay out the normal version, asked me to do it. For me personally, the article is very useful, so all this work is exclusively blide !
While playing Team Fortess 2 while listening to music, I was very indignant because of the impossibility of adjusting the volume of the Clementine player separately from the overall volume. But I don’t have extra keys on the keyboard, they are all used.
A nontrivial task should have a nontrivial solution, so I decided to emulate keystrokes through my android device using http. Ignorance of Java and Python didn’t prevent anything, it’s not for nothing that I have an ext3 partition on my hard drive.
First you needed to know the list of supported and free keys. In Ubuntu, you can use the xmodmap utility and the /usr/library/X11/*keysum.h files for me:
#define XF86XK_Launch0 0x1008FF40 … #define XF86XK_LaunchF 0x1008FF4F
We need these key codes (I chose only 2); for example, you can find out the key code with the designation "XF86XK_Launch1" using the command "xmodmap -pk | preg 'Launch1'
"We will get the code" 156 "(I have chosen 156 and 157).
')
Server
Using the best possible logic, I realized that I would write a tcp server in Python 3 that I did not know using the http module. This stage did not cause any difficulties, because the module has a fairly good and clear basis for writing a tcp server, namely the classes “BaseHTTPRequestHandler” and “SimpleHTTPRequestHandler”. To emulate keystrokes, “pyatspi.registry” was used, well, there’s actually nothing to comment on.
In the process of debugging, it seemed to me that it would be very useful to know the response time, but then something interesting happened; In the emulator, this feature worked as it should, but the response time obtained when working with a physical device made me rethink ideas about the structure of the world. Gradually, I began to feel that I was a programming guru and a master of time. Otherwise, how would I manage to reduce the response time to negative values? I am ready to listen to your theory on this precedent.
import pyatspi, time import http.server import socketserver class HttpKeyboard(http.server.BaseHTTPRequestHandler): server_version = "SimpleHTTP/0.1" def do_GET(self): """Serve a GET request.""" reg = pyatspi.Registry.generateKeyboardEvent path = self.path.split('/') if len(path) == 3: ms = int(round(time.time() * 1000)) - int(path[2]) reg(int(path[1]), None, pyatspi.KEY_PRESSRELEASE) print ("key %s - %s ms" % (path[1], ms)) f = self.send_head() def send_head(self): self.send_response(200) self.send_header("Content-type", "text/html; charset=utf-8") self.send_header("Content-Length", 0) self.end_headers() httpd = socketserver.TCPServer(("", 8000), HttpKeyboard) print("serving at port", 8000) if __name__ == "__main__": httpd.serve_forever()
There is an example of a request handler in this library — the
SimpleHTTPRequestHandler class, which can help a
lot when working with it.
By the way, if you run the script in the console, then after processing the requests it will output:
key 156 - 527 ms
// ( )
192.168.0.101 - - [07/Jan/2013 19:57:09] "GET /156/1357574229198 HTTP/1.1" 200
In this case:
156 - key code
1357574229198 - time to press a button on the dual extra keyboard
I decided to add http-headers so that the result of the request could be processed on the device with ready-made tools.
Android application
For asynchronous requests, I chose the Android Asynchronous Http Client. The devices are in the same wifi-grid, so the internal ip was used, nothing more interesting at this stage I found except the hostile System.currentTimeMillis (). I will throw off the complete sorts at the end, and here I will leave the function of the request itself.
Java public void KeyHttp(String key) { AsyncHttpClient client = new AsyncHttpClient(); EditText edit = (EditText) findViewById(R.id.editText1); client.get("http://"+edit.getText()+"/"+key+"/"+System.currentTimeMillis(), new AsyncHttpResponseHandler() { @Override public void onSuccess(String response) { this.log("success result"); } @Override public void onStart() { this.log("starting"); } @Override public void onFailure(Throwable error) { this.log("failure result"); } public void log(String text) { TextView view = (TextView) findViewById(R.id.textView1); view.setText(text); } }); }
Total
Run the server and install the application on the device.
Well, now everything is ready for a comfortable increase in playing time on a linux-machine in Team Fortress 2 under the rebellious rhythms of The Offspring.
Keys can be used any and in any quantity. I often see with friends TV and PCs connected via hdmi, but being in different rooms, such an IT-life-hack, I think, they would have liked. In fact, the scope of this tool is quite wide: from home media centers to non-home media centers.
Thank you for your interest in the material.
References:
Android Asynchronous Http Client (
http://loopj.com/android-async-http/ )
http.server (
http://docs.python.org/3.2/library/http.server.html )
We write our first application on Android (
http://habrahabr.ru/post/109944/ )
man xmodmap
* I did not use the blue electrical tape specially, I would like to use the phone separately from the keyboard