]> git.sur5r.net Git - i3/i3/commitdiff
committed the wrong file
authorMichael Stapelberg <michael@stapelberg.de>
Fri, 12 Mar 2010 02:06:40 +0000 (03:06 +0100)
committerMichael Stapelberg <michael@stapelberg.de>
Fri, 12 Mar 2010 02:06:40 +0000 (03:06 +0100)
docs/ipc [new file with mode: 0644]
docs/ipc.html [deleted file]

diff --git a/docs/ipc b/docs/ipc
new file mode 100644 (file)
index 0000000..d1783b2
--- /dev/null
+++ b/docs/ipc
@@ -0,0 +1,146 @@
+IPC interface (interprocess communication)
+==========================================
+Michael Stapelberg <michael+i3@stapelberg.de>
+March 2010
+
+This document describes how to interface with i3 from a separate process. This
+is useful for example to remote-control i3 (to write test cases for example) or
+to get various information like the current workspaces to implement an external
+workspace bar.
+
+The method of choice for IPC in our case is a unix socket because it has very
+little overhead on both sides and is usually available without headaches in
+most languages. In the default configuration file, no ipc-socket path is
+specified and thus no socket is created. The standard path (which +i3-msg+ and
++i3-input+ use) is +/tmp/i3-ipc.sock+.
+
+== Establishing a connection
+
+To establish a connection, simply open the IPC socket. The following code
+snippet illustrates this in Perl:
+
+-------------------------------------------------------------
+use IO::Socket::UNIX;
+my $sock = IO::Socket::UNIX->new(Peer => '/tmp/i3-ipc.sock');
+-------------------------------------------------------------
+
+== Sending messages to i3
+
+To send a message to i3, you have to format in the binary message format which
+i3 expects. This format specifies a magic string in the beginning to ensure
+the integrity of messages (to prevent follow-up errors). Afterwards follows
+the length of the payload of the message as 32-bit integer and the type of
+the message as 32-bit integer (the integers are not converted, so they are
+in native byte order).
+
+The magic string currently is "i3-ipc" and will only be changed when a change
+in the IPC API is done which breaks compatibility (we hope that we don’t need
+to do that).
+
+Currently implemented message types are the following:
+
+0 (COMMAND)::
+       The payload of the message is a command for i3 (like the commands you
+       can bind to keys in the configuration file) and will be executed
+       directly after receiving it. There is no reply to this message.
+1 (GET_WORKSPACES)::
+       Gets the current workspaces. The reply will be a JSON-encoded list of
+       workspaces (see the reply section).
+
+So, a typical message could look like this:
+--------------------------------------------------
+"i3-ipc" <message length> <message type> <payload>
+--------------------------------------------------
+
+Or, as a hexdump:
+------------------------------------------------------------------------------
+00000000  69 33 2d 69 70 63 04 00  00 00 00 00 00 00 65 78  |i3-ipc........ex|
+00000010  69 74 0a                                          |it.|
+------------------------------------------------------------------------------
+
+To generate and send such a message, you could use the following code in Perl:
+------------------------------------------------------------
+sub format_ipc_command {
+    my ($msg) = @_;
+    my $len;
+    # Get the real byte count (vs. amount of characters)
+    { use bytes; $len = length($msg); }
+    return "i3-ipc" . pack("LL", $len, 0) . $msg;
+}
+
+$sock->write(format_ipc_command("exit"));
+------------------------------------------------------------
+
+== Receiving replies from i3
+
+Replies of i3 usually consist of a simple string (the length of the string
+is the message_length, so you can consider them length-prefixed) which in turn
+contain the JSON serialization of a data structure. For example, the
+GET_WORKSPACES message returns an array of workspaces (each workspace is a map
+with certain attributes).
+
+=== Reply format
+
+The reply format is identical to the normal message format. There also is
+the magic string, then the message length, then the message type and the
+payload.
+
+The following reply types are implemented:
+
+1 (GET_WORKSPACES)::
+       Reply to the GET_WORKSPACES message.
+
+=== GET_WORKSPACES reply
+
+The reply consists of a serialized list of workspaces. Each workspace has the
+following properties:
+
+num (integer)::
+       The internal number of the workspace. Corresponds to the command
+       to switch to this workspace.
+name (string)::
+       The name of this workspace (by default num+1), as changed by the
+       user. Encoded in UTF-8.
+visible (boolean)::
+       Whether this workspace is currently visible on an output (multiple
+       workspaces can be visible at the same time).
+focused (boolean)::
+       Whether this workspace currently has the focus (only one workspace
+       can have the focus at the same time).
+rect (map)::
+       The rectangle of this workspace (equals the rect of the output it
+       is on), consists of x, y, width, height.
+output (string)::
+       The video output this workspace is on (LVDS1, VGA1, …).
+
+*Example:*
+-------------------
+[
+ {
+  "num": 0,
+  "name": "1",
+  "visible": true,
+  "focused": true,
+  "rect": {
+   "x": 0,
+   "y": 0,
+   "width": 1280,
+   "height": 800
+  },
+  "output": "LVDS1"
+ },
+ {
+  "num": 1,
+  "name": "2",
+  "visible": false,
+  "focused": false,
+  "rect": {
+   "x": 0,
+   "y": 0,
+   "width": 1280,
+   "height": 800
+  },
+  "output": "LVDS1"
+ }
+]
+-------------------
diff --git a/docs/ipc.html b/docs/ipc.html
deleted file mode 100644 (file)
index 298f9ef..0000000
+++ /dev/null
@@ -1,766 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"\r
-    "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">\r
-<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">\r
-<head>\r
-<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />\r
-<meta name="generator" content="AsciiDoc 8.5.2" />\r
-<title>IPC interface (interprocess communication)</title>\r
-<style type="text/css">\r
-/* Debug borders */\r
-p, li, dt, dd, div, pre, h1, h2, h3, h4, h5, h6 {\r
-/*\r
-  border: 1px solid red;\r
-*/\r
-}\r
-\r
-body {\r
-  margin: 1em 5% 1em 5%;\r
-}\r
-\r
-a {\r
-  color: blue;\r
-  text-decoration: underline;\r
-}\r
-a:visited {\r
-  color: fuchsia;\r
-}\r
-\r
-em {\r
-  font-style: italic;\r
-  color: navy;\r
-}\r
-\r
-strong {\r
-  font-weight: bold;\r
-  color: #083194;\r
-}\r
-\r
-tt {\r
-  color: navy;\r
-}\r
-\r
-h1, h2, h3, h4, h5, h6 {\r
-  color: #527bbd;\r
-  font-family: sans-serif;\r
-  margin-top: 1.2em;\r
-  margin-bottom: 0.5em;\r
-  line-height: 1.3;\r
-}\r
-\r
-h1, h2, h3 {\r
-  border-bottom: 2px solid silver;\r
-}\r
-h2 {\r
-  padding-top: 0.5em;\r
-}\r
-h3 {\r
-  float: left;\r
-}\r
-h3 + * {\r
-  clear: left;\r
-}\r
-\r
-div.sectionbody {\r
-  font-family: serif;\r
-  margin-left: 0;\r
-}\r
-\r
-hr {\r
-  border: 1px solid silver;\r
-}\r
-\r
-p {\r
-  margin-top: 0.5em;\r
-  margin-bottom: 0.5em;\r
-}\r
-\r
-ul, ol, li > p {\r
-  margin-top: 0;\r
-}\r
-\r
-pre {\r
-  padding: 0;\r
-  margin: 0;\r
-}\r
-\r
-span#author {\r
-  color: #527bbd;\r
-  font-family: sans-serif;\r
-  font-weight: bold;\r
-  font-size: 1.1em;\r
-}\r
-span#email {\r
-}\r
-span#revnumber, span#revdate, span#revremark {\r
-  font-family: sans-serif;\r
-}\r
-\r
-div#footer {\r
-  font-family: sans-serif;\r
-  font-size: small;\r
-  border-top: 2px solid silver;\r
-  padding-top: 0.5em;\r
-  margin-top: 4.0em;\r
-}\r
-div#footer-text {\r
-  float: left;\r
-  padding-bottom: 0.5em;\r
-}\r
-div#footer-badges {\r
-  float: right;\r
-  padding-bottom: 0.5em;\r
-}\r
-\r
-div#preamble {\r
-  margin-top: 1.5em;\r
-  margin-bottom: 1.5em;\r
-}\r
-div.tableblock, div.imageblock, div.exampleblock, div.verseblock,\r
-div.quoteblock, div.literalblock, div.listingblock, div.sidebarblock,\r
-div.admonitionblock {\r
-  margin-top: 1.0em;\r
-  margin-bottom: 1.5em;\r
-}\r
-div.admonitionblock {\r
-  margin-top: 2.0em;\r
-  margin-bottom: 2.0em;\r
-  margin-right: 10%;\r
-  color: #606060;\r
-}\r
-\r
-div.content { /* Block element content. */\r
-  padding: 0;\r
-}\r
-\r
-/* Block element titles. */\r
-div.title, caption.title {\r
-  color: #527bbd;\r
-  font-family: sans-serif;\r
-  font-weight: bold;\r
-  text-align: left;\r
-  margin-top: 1.0em;\r
-  margin-bottom: 0.5em;\r
-}\r
-div.title + * {\r
-  margin-top: 0;\r
-}\r
-\r
-td div.title:first-child {\r
-  margin-top: 0.0em;\r
-}\r
-div.content div.title:first-child {\r
-  margin-top: 0.0em;\r
-}\r
-div.content + div.title {\r
-  margin-top: 0.0em;\r
-}\r
-\r
-div.sidebarblock > div.content {\r
-  background: #ffffee;\r
-  border: 1px solid silver;\r
-  padding: 0.5em;\r
-}\r
-\r
-div.listingblock > div.content {\r
-  border: 1px solid silver;\r
-  background: #f4f4f4;\r
-  padding: 0.5em;\r
-}\r
-\r
-div.quoteblock, div.verseblock {\r
-  padding-left: 1.0em;\r
-  margin-left: 1.0em;\r
-  margin-right: 10%;\r
-  border-left: 5px solid #dddddd;\r
-  color: #777777;\r
-}\r
-\r
-div.quoteblock > div.attribution {\r
-  padding-top: 0.5em;\r
-  text-align: right;\r
-}\r
-\r
-div.verseblock > div.content {\r
-  white-space: pre;\r
-}\r
-div.verseblock > div.attribution {\r
-  padding-top: 0.75em;\r
-  text-align: left;\r
-}\r
-/* DEPRECATED: Pre version 8.2.7 verse style literal block. */\r
-div.verseblock + div.attribution {\r
-  text-align: left;\r
-}\r
-\r
-div.admonitionblock .icon {\r
-  vertical-align: top;\r
-  font-size: 1.1em;\r
-  font-weight: bold;\r
-  text-decoration: underline;\r
-  color: #527bbd;\r
-  padding-right: 0.5em;\r
-}\r
-div.admonitionblock td.content {\r
-  padding-left: 0.5em;\r
-  border-left: 3px solid #dddddd;\r
-}\r
-\r
-div.exampleblock > div.content {\r
-  border-left: 3px solid #dddddd;\r
-  padding-left: 0.5em;\r
-}\r
-\r
-div.imageblock div.content { padding-left: 0; }\r
-span.image img { border-style: none; }\r
-a.image:visited { color: white; }\r
-\r
-dl {\r
-  margin-top: 0.8em;\r
-  margin-bottom: 0.8em;\r
-}\r
-dt {\r
-  margin-top: 0.5em;\r
-  margin-bottom: 0;\r
-  font-style: normal;\r
-  color: navy;\r
-}\r
-dd > *:first-child {\r
-  margin-top: 0.1em;\r
-}\r
-\r
-ul, ol {\r
-    list-style-position: outside;\r
-}\r
-ol.arabic {\r
-  list-style-type: decimal;\r
-}\r
-ol.loweralpha {\r
-  list-style-type: lower-alpha;\r
-}\r
-ol.upperalpha {\r
-  list-style-type: upper-alpha;\r
-}\r
-ol.lowerroman {\r
-  list-style-type: lower-roman;\r
-}\r
-ol.upperroman {\r
-  list-style-type: upper-roman;\r
-}\r
-\r
-div.compact ul, div.compact ol,\r
-div.compact p, div.compact p,\r
-div.compact div, div.compact div {\r
-  margin-top: 0.1em;\r
-  margin-bottom: 0.1em;\r
-}\r
-\r
-div.tableblock > table {\r
-  border: 3px solid #527bbd;\r
-}\r
-thead, p.table.header {\r
-  font-family: sans-serif;\r
-  font-weight: bold;\r
-}\r
-tfoot {\r
-  font-weight: bold;\r
-}\r
-td > div.verse {\r
-  white-space: pre;\r
-}\r
-p.table {\r
-  margin-top: 0;\r
-}\r
-/* Because the table frame attribute is overriden by CSS in most browsers. */\r
-div.tableblock > table[frame="void"] {\r
-  border-style: none;\r
-}\r
-div.tableblock > table[frame="hsides"] {\r
-  border-left-style: none;\r
-  border-right-style: none;\r
-}\r
-div.tableblock > table[frame="vsides"] {\r
-  border-top-style: none;\r
-  border-bottom-style: none;\r
-}\r
-\r
-\r
-div.hdlist {\r
-  margin-top: 0.8em;\r
-  margin-bottom: 0.8em;\r
-}\r
-div.hdlist tr {\r
-  padding-bottom: 15px;\r
-}\r
-dt.hdlist1.strong, td.hdlist1.strong {\r
-  font-weight: bold;\r
-}\r
-td.hdlist1 {\r
-  vertical-align: top;\r
-  font-style: normal;\r
-  padding-right: 0.8em;\r
-  color: navy;\r
-}\r
-td.hdlist2 {\r
-  vertical-align: top;\r
-}\r
-div.hdlist.compact tr {\r
-  margin: 0;\r
-  padding-bottom: 0;\r
-}\r
-\r
-.comment {\r
-  background: yellow;\r
-}\r
-\r
-.footnote, .footnoteref {\r
-  font-size: 0.8em;\r
-}\r
-\r
-span.footnote, span.footnoteref {\r
-  vertical-align: super;\r
-}\r
-\r
-#footnotes {\r
-  margin: 20px 0 20px 0;\r
-  padding: 7px 0 0 0;\r
-}\r
-\r
-#footnotes div.footnote {\r
-  margin: 0 0 5px 0;\r
-}\r
-\r
-#footnotes hr {\r
-  border: none;\r
-  border-top: 1px solid silver;\r
-  height: 1px;\r
-  text-align: left;\r
-  margin-left: 0;\r
-  width: 20%;\r
-  min-width: 100px;\r
-}\r
-\r
-\r
-@media print {\r
-  div#footer-badges { display: none; }\r
-}\r
-\r
-div#toc {\r
-  margin-bottom: 2.5em;\r
-}\r
-\r
-div#toctitle {\r
-  color: #527bbd;\r
-  font-family: sans-serif;\r
-  font-size: 1.1em;\r
-  font-weight: bold;\r
-  margin-top: 1.0em;\r
-  margin-bottom: 0.1em;\r
-}\r
-\r
-div.toclevel1, div.toclevel2, div.toclevel3, div.toclevel4 {\r
-  margin-top: 0;\r
-  margin-bottom: 0;\r
-}\r
-div.toclevel2 {\r
-  margin-left: 2em;\r
-  font-size: 0.9em;\r
-}\r
-div.toclevel3 {\r
-  margin-left: 4em;\r
-  font-size: 0.9em;\r
-}\r
-div.toclevel4 {\r
-  margin-left: 6em;\r
-  font-size: 0.9em;\r
-}\r
-/* Workarounds for IE6's broken and incomplete CSS2. */\r
-\r
-div.sidebar-content {\r
-  background: #ffffee;\r
-  border: 1px solid silver;\r
-  padding: 0.5em;\r
-}\r
-div.sidebar-title, div.image-title {\r
-  color: #527bbd;\r
-  font-family: sans-serif;\r
-  font-weight: bold;\r
-  margin-top: 0.0em;\r
-  margin-bottom: 0.5em;\r
-}\r
-\r
-div.listingblock div.content {\r
-  border: 1px solid silver;\r
-  background: #f4f4f4;\r
-  padding: 0.5em;\r
-}\r
-\r
-div.quoteblock-attribution {\r
-  padding-top: 0.5em;\r
-  text-align: right;\r
-}\r
-\r
-div.verseblock-content {\r
-  white-space: pre;\r
-}\r
-div.verseblock-attribution {\r
-  padding-top: 0.75em;\r
-  text-align: left;\r
-}\r
-\r
-div.exampleblock-content {\r
-  border-left: 3px solid #dddddd;\r
-  padding-left: 0.5em;\r
-}\r
-\r
-/* IE6 sets dynamically generated links as visited. */\r
-div#toc a:visited { color: blue; }\r
-</style>\r
-<script type="text/javascript">\r
-/*<![CDATA[*/\r
-window.onload = function(){asciidoc.footnotes(); asciidoc.toc(2);}\r
-var asciidoc = {  // Namespace.\r
-\r
-/////////////////////////////////////////////////////////////////////\r
-// Table Of Contents generator\r
-/////////////////////////////////////////////////////////////////////\r
-\r
-/* Author: Mihai Bazon, September 2002\r
- * http://students.infoiasi.ro/~mishoo\r
- *\r
- * Table Of Content generator\r
- * Version: 0.4\r
- *\r
- * Feel free to use this script under the terms of the GNU General Public\r
- * License, as long as you do not remove or alter this notice.\r
- */\r
-\r
- /* modified by Troy D. Hanson, September 2006. License: GPL */\r
- /* modified by Stuart Rackham, 2006, 2009. License: GPL */\r
-\r
-// toclevels = 1..4.\r
-toc: function (toclevels) {\r
-\r
-  function getText(el) {\r
-    var text = "";\r
-    for (var i = el.firstChild; i != null; i = i.nextSibling) {\r
-      if (i.nodeType == 3 /* Node.TEXT_NODE */) // IE doesn't speak constants.\r
-        text += i.data;\r
-      else if (i.firstChild != null)\r
-        text += getText(i);\r
-    }\r
-    return text;\r
-  }\r
-\r
-  function TocEntry(el, text, toclevel) {\r
-    this.element = el;\r
-    this.text = text;\r
-    this.toclevel = toclevel;\r
-  }\r
-\r
-  function tocEntries(el, toclevels) {\r
-    var result = new Array;\r
-    var re = new RegExp('[hH]([2-'+(toclevels+1)+'])');\r
-    // Function that scans the DOM tree for header elements (the DOM2\r
-    // nodeIterator API would be a better technique but not supported by all\r
-    // browsers).\r
-    var iterate = function (el) {\r
-      for (var i = el.firstChild; i != null; i = i.nextSibling) {\r
-        if (i.nodeType == 1 /* Node.ELEMENT_NODE */) {\r
-          var mo = re.exec(i.tagName);\r
-          if (mo && (i.getAttribute("class") || i.getAttribute("className")) != "float") {\r
-            result[result.length] = new TocEntry(i, getText(i), mo[1]-1);\r
-          }\r
-          iterate(i);\r
-        }\r
-      }\r
-    }\r
-    iterate(el);\r
-    return result;\r
-  }\r
-\r
-  var toc = document.getElementById("toc");\r
-  var entries = tocEntries(document.getElementById("content"), toclevels);\r
-  for (var i = 0; i < entries.length; ++i) {\r
-    var entry = entries[i];\r
-    if (entry.element.id == "")\r
-      entry.element.id = "_toc_" + i;\r
-    var a = document.createElement("a");\r
-    a.href = "#" + entry.element.id;\r
-    a.appendChild(document.createTextNode(entry.text));\r
-    var div = document.createElement("div");\r
-    div.appendChild(a);\r
-    div.className = "toclevel" + entry.toclevel;\r
-    toc.appendChild(div);\r
-  }\r
-  if (entries.length == 0)\r
-    toc.parentNode.removeChild(toc);\r
-},\r
-\r
-\r
-/////////////////////////////////////////////////////////////////////\r
-// Footnotes generator\r
-/////////////////////////////////////////////////////////////////////\r
-\r
-/* Based on footnote generation code from:\r
- * http://www.brandspankingnew.net/archive/2005/07/format_footnote.html\r
- */\r
-\r
-footnotes: function () {\r
-  var cont = document.getElementById("content");\r
-  var noteholder = document.getElementById("footnotes");\r
-  var spans = cont.getElementsByTagName("span");\r
-  var refs = {};\r
-  var n = 0;\r
-  for (i=0; i<spans.length; i++) {\r
-    if (spans[i].className == "footnote") {\r
-      n++;\r
-      // Use [\s\S] in place of . so multi-line matches work.\r
-      // Because JavaScript has no s (dotall) regex flag.\r
-      note = spans[i].innerHTML.match(/\s*\[([\s\S]*)]\s*/)[1];\r
-      noteholder.innerHTML +=\r
-        "<div class='footnote' id='_footnote_" + n + "'>" +\r
-        "<a href='#_footnoteref_" + n + "' title='Return to text'>" +\r
-        n + "</a>. " + note + "</div>";\r
-      spans[i].innerHTML =\r
-        "[<a id='_footnoteref_" + n + "' href='#_footnote_" + n +\r
-        "' title='View footnote' class='footnote'>" + n + "</a>]";\r
-      var id =spans[i].getAttribute("id");\r
-      if (id != null) refs["#"+id] = n;\r
-    }\r
-  }\r
-  if (n == 0)\r
-    noteholder.parentNode.removeChild(noteholder);\r
-  else {\r
-    // Process footnoterefs.\r
-    for (i=0; i<spans.length; i++) {\r
-      if (spans[i].className == "footnoteref") {\r
-        var href = spans[i].getElementsByTagName("a")[0].getAttribute("href");\r
-        href = href.match(/#.*/)[0];  // Because IE return full URL.\r
-        n = refs[href];\r
-        spans[i].innerHTML =\r
-          "[<a href='#_footnote_" + n +\r
-          "' title='View footnote' class='footnote'>" + n + "</a>]";\r
-      }\r
-    }\r
-  }\r
-}\r
-\r
-}\r
-/*]]>*/\r
-</script>\r
-</head>\r
-<body>\r
-<div id="header">\r
-<h1>IPC interface (interprocess communication)</h1>\r
-<span id="author">Michael Stapelberg</span><br />\r
-<span id="email"><tt>&lt;<a href="mailto:michael+i3@stapelberg.de">michael+i3@stapelberg.de</a>&gt;</tt></span><br />\r
-<span id="revdate">March 2010</span>\r
-<div id="toc">\r
-  <div id="toctitle">Table of Contents</div>\r
-  <noscript><p><b>JavaScript must be enabled in your browser to display the table of contents.</b></p></noscript>\r
-</div>\r
-</div>\r
-<div id="content">\r
-<div id="preamble">\r
-<div class="sectionbody">\r
-<div class="paragraph"><p>This document describes how to interface with i3 from a separate process. This\r
-is useful for example to remote-control i3 (to write test cases for example) or\r
-to get various information like the current workspaces to implement an external\r
-workspace bar.</p></div>\r
-<div class="paragraph"><p>The method of choice for IPC in our case is a unix socket because it has very\r
-little overhead on both sides and is usually available without headaches in\r
-most languages. In the default configuration file, no ipc-socket path is\r
-specified and thus no socket is created. The standard path (which <tt>i3-msg</tt> and\r
-<tt>i3-input</tt> use) is <tt>/tmp/i3-ipc.sock</tt>.</p></div>\r
-</div>\r
-</div>\r
-<h2 id="_establishing_a_connection">1. Establishing a connection</h2>\r
-<div class="sectionbody">\r
-<div class="paragraph"><p>To establish a connection, simply open the IPC socket. The following code\r
-snippet illustrates this in Perl:</p></div>\r
-<div class="listingblock">\r
-<div class="content">\r
-<pre><tt>use IO::Socket::UNIX;\r
-my $sock = IO::Socket::UNIX-&gt;new(Peer =&gt; '/tmp/i3-ipc.sock');</tt></pre>\r
-</div></div>\r
-</div>\r
-<h2 id="_sending_messages_to_i3">2. Sending messages to i3</h2>\r
-<div class="sectionbody">\r
-<div class="paragraph"><p>To send a message to i3, you have to format in the binary message format which\r
-i3 expects. This format specifies a magic string in the beginning to ensure\r
-the integrity of messages (to prevent follow-up errors). Afterwards follows\r
-the length of the payload of the message as 32-bit integer and the type of\r
-the message as 32-bit integer (the integers are not converted, so they are\r
-in native byte order).</p></div>\r
-<div class="paragraph"><p>The magic string currently is "i3-ipc" and will only be changed when a change\r
-in the IPC API is done which breaks compatibility (we hope that we don’t need\r
-to do that).</p></div>\r
-<div class="paragraph"><p>Currently implemented message types are the following:</p></div>\r
-<div class="dlist"><dl>\r
-<dt class="hdlist1">\r
-0 (COMMAND)\r
-</dt>\r
-<dd>\r
-<p>\r
-        The payload of the message is a command for i3 (like the commands you\r
-        can bind to keys in the configuration file) and will be executed\r
-        directly after receiving it. There is no reply to this message.\r
-</p>\r
-</dd>\r
-<dt class="hdlist1">\r
-1 (GET_WORKSPACES)\r
-</dt>\r
-<dd>\r
-<p>\r
-        Gets the current workspaces. The reply will be a JSON-encoded list of\r
-        workspaces (see the reply section).\r
-</p>\r
-</dd>\r
-</dl></div>\r
-<div class="paragraph"><p>So, a typical message could look like this:</p></div>\r
-<div class="listingblock">\r
-<div class="content">\r
-<pre><tt>"i3-ipc" &lt;message length&gt; &lt;message type&gt; &lt;payload&gt;</tt></pre>\r
-</div></div>\r
-<div class="paragraph"><p>Or, as a hexdump:</p></div>\r
-<div class="listingblock">\r
-<div class="content">\r
-<pre><tt>00000000  69 33 2d 69 70 63 04 00  00 00 00 00 00 00 65 78  |i3-ipc........ex|\r
-00000010  69 74 0a                                          |it.|</tt></pre>\r
-</div></div>\r
-<div class="paragraph"><p>To generate and send such a message, you could use the following code in Perl:</p></div>\r
-<div class="listingblock">\r
-<div class="content">\r
-<pre><tt>sub format_ipc_command {\r
-    my ($msg) = @_;\r
-    my $len;\r
-    # Get the real byte count (vs. amount of characters)\r
-    { use bytes; $len = length($msg); }\r
-    return "i3-ipc" . pack("LL", $len, 0) . $msg;\r
-}\r
-\r
-$sock-&gt;write(format_ipc_command("exit"));</tt></pre>\r
-</div></div>\r
-</div>\r
-<h2 id="_receiving_replies_from_i3">3. Receiving replies from i3</h2>\r
-<div class="sectionbody">\r
-<div class="paragraph"><p>Replies of i3 usually consist of a simple string (the length of the string\r
-is the message_length, so you can consider them length-prefixed) which in turn\r
-contain the JSON serialization of a data structure. For example, the\r
-GET_WORKSPACES message returns an array of workspaces (each workspace is a map\r
-with certain attributes).</p></div>\r
-<h3 id="_reply_format">3.1. Reply format</h3><div style="clear:left"></div>\r
-<div class="paragraph"><p>The reply format is identical to the normal message format. There also is\r
-the magic string, then the message length, then the message type and the\r
-payload.</p></div>\r
-<div class="paragraph"><p>The following reply types are implemented:</p></div>\r
-<div class="dlist"><dl>\r
-<dt class="hdlist1">\r
-1 (GET_WORKSPACES)\r
-</dt>\r
-<dd>\r
-<p>\r
-        Reply to the GET_WORKSPACES message.\r
-</p>\r
-</dd>\r
-</dl></div>\r
-<h3 id="_get_workspaces_reply">3.2. GET_WORKSPACES reply</h3><div style="clear:left"></div>\r
-<div class="paragraph"><p>The reply consists of a serialized list of workspaces. Each workspace has the\r
-following properties:</p></div>\r
-<div class="dlist"><dl>\r
-<dt class="hdlist1">\r
-num (integer)\r
-</dt>\r
-<dd>\r
-<p>\r
-        The internal number of the workspace. Corresponds to the command\r
-        to switch to this workspace.\r
-</p>\r
-</dd>\r
-<dt class="hdlist1">\r
-name (string)\r
-</dt>\r
-<dd>\r
-<p>\r
-        The name of this workspace (by default num+1), as changed by the\r
-        user. Encoded in UTF-8.\r
-</p>\r
-</dd>\r
-<dt class="hdlist1">\r
-visible (boolean)\r
-</dt>\r
-<dd>\r
-<p>\r
-        Whether this workspace is currently visible on an output (multiple\r
-        workspaces can be visible at the same time).\r
-</p>\r
-</dd>\r
-<dt class="hdlist1">\r
-focused (boolean)\r
-</dt>\r
-<dd>\r
-<p>\r
-        Whether this workspace currently has the focus (only one workspace\r
-        can have the focus at the same time).\r
-</p>\r
-</dd>\r
-<dt class="hdlist1">\r
-rect (map)\r
-</dt>\r
-<dd>\r
-<p>\r
-        The rectangle of this workspace (equals the rect of the output it\r
-        is on), consists of x, y, width, height.\r
-</p>\r
-</dd>\r
-<dt class="hdlist1">\r
-output (string)\r
-</dt>\r
-<dd>\r
-<p>\r
-        The video output this workspace is on (LVDS1, VGA1, …).\r
-</p>\r
-</dd>\r
-</dl></div>\r
-<div class="paragraph"><p><strong>Example:</strong></p></div>\r
-<div class="listingblock">\r
-<div class="content">\r
-<pre><tt>[\r
- {\r
-  "num": 0,\r
-  "name": "1",\r
-  "visible": true,\r
-  "focused": true,\r
-  "rect": {\r
-   "x": 0,\r
-   "y": 0,\r
-   "width": 1280,\r
-   "height": 800\r
-  },\r
-  "output": "LVDS1"\r
- },\r
- {\r
-  "num": 1,\r
-  "name": "2",\r
-  "visible": false,\r
-  "focused": false,\r
-  "rect": {\r
-   "x": 0,\r
-   "y": 0,\r
-   "width": 1280,\r
-   "height": 800\r
-  },\r
-  "output": "LVDS1"\r
- }\r
-]</tt></pre>\r
-</div></div>\r
-</div>\r
-</div>\r
-<div id="footnotes"><hr /></div>\r
-<div id="footer">\r
-<div id="footer-text">\r
-Last updated 2010-03-12 03:04:46 CEST\r
-</div>\r
-</div>\r
-</body>\r
-</html>\r