Sophie

Sophie

distrib > Fedora > 14 > x86_64 > by-pkgid > c67c6057ffd14254a26624517a2352e6 > files > 528

i3-doc-3.e-3.bf1.fc14.noarch.rpm

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<title>i3: src/mainx.c Source File</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<link href="doxygen.css" rel="stylesheet" type="text/css"/>
</head>
<body>
<!-- Generated by Doxygen 1.6.2-20100208 -->
<div class="navigation" id="top">
  <div class="tabs">
    <ul>
      <li><a href="index.html"><span>Main&nbsp;Page</span></a></li>
      <li><a href="annotated.html"><span>Data&nbsp;Structures</span></a></li>
      <li class="current"><a href="files.html"><span>Files</span></a></li>
    </ul>
  </div>
  <div class="tabs">
    <ul>
      <li><a href="files.html"><span>File&nbsp;List</span></a></li>
      <li><a href="globals.html"><span>Globals</span></a></li>
    </ul>
  </div>
<h1>src/mainx.c</h1><a href="a00071.html">Go to the documentation of this file.</a><div class="fragment"><pre class="fragment"><a name="l00001"></a>00001 <span class="comment">/*</span>
<a name="l00002"></a>00002 <span class="comment"> * vim:ts=8:expandtab</span>
<a name="l00003"></a>00003 <span class="comment"> *</span>
<a name="l00004"></a>00004 <span class="comment"> * i3 - an improved dynamic tiling window manager</span>
<a name="l00005"></a>00005 <span class="comment"> *</span>
<a name="l00006"></a>00006 <span class="comment"> * © 2009-2010 Michael Stapelberg and contributors</span>
<a name="l00007"></a>00007 <span class="comment"> *</span>
<a name="l00008"></a>00008 <span class="comment"> * See file LICENSE for license information.</span>
<a name="l00009"></a>00009 <span class="comment"> *</span>
<a name="l00010"></a>00010 <span class="comment"> */</span>
<a name="l00011"></a>00011 <span class="preprocessor">#include &lt;stdio.h&gt;</span>
<a name="l00012"></a>00012 <span class="preprocessor">#include &lt;stdlib.h&gt;</span>
<a name="l00013"></a>00013 <span class="preprocessor">#include &lt;string.h&gt;</span>
<a name="l00014"></a>00014 <span class="preprocessor">#include &lt;sys/types.h&gt;</span>
<a name="l00015"></a>00015 <span class="preprocessor">#include &lt;unistd.h&gt;</span>
<a name="l00016"></a>00016 <span class="preprocessor">#include &lt;stdbool.h&gt;</span>
<a name="l00017"></a>00017 <span class="preprocessor">#include &lt;assert.h&gt;</span>
<a name="l00018"></a>00018 <span class="preprocessor">#include &lt;limits.h&gt;</span>
<a name="l00019"></a>00019 <span class="preprocessor">#include &lt;locale.h&gt;</span>
<a name="l00020"></a>00020 <span class="preprocessor">#include &lt;fcntl.h&gt;</span>
<a name="l00021"></a>00021 <span class="preprocessor">#include &lt;getopt.h&gt;</span>
<a name="l00022"></a>00022 
<a name="l00023"></a>00023 <span class="preprocessor">#include &lt;X11/XKBlib.h&gt;</span>
<a name="l00024"></a>00024 <span class="preprocessor">#include &lt;X11/extensions/XKB.h&gt;</span>
<a name="l00025"></a>00025 
<a name="l00026"></a>00026 <span class="preprocessor">#include &lt;xcb/xcb.h&gt;</span>
<a name="l00027"></a>00027 <span class="preprocessor">#include &lt;xcb/xcb_atom.h&gt;</span>
<a name="l00028"></a>00028 <span class="preprocessor">#include &lt;xcb/xcb_aux.h&gt;</span>
<a name="l00029"></a>00029 <span class="preprocessor">#include &lt;xcb/xcb_event.h&gt;</span>
<a name="l00030"></a>00030 <span class="preprocessor">#include &lt;xcb/xcb_property.h&gt;</span>
<a name="l00031"></a>00031 <span class="preprocessor">#include &lt;xcb/xcb_keysyms.h&gt;</span>
<a name="l00032"></a>00032 <span class="preprocessor">#include &lt;xcb/xcb_icccm.h&gt;</span>
<a name="l00033"></a>00033 
<a name="l00034"></a>00034 <span class="preprocessor">#include &lt;ev.h&gt;</span>
<a name="l00035"></a>00035 
<a name="l00036"></a>00036 <span class="preprocessor">#include &quot;<a class="code" href="a00034.html">config.h</a>&quot;</span>
<a name="l00037"></a>00037 <span class="preprocessor">#include &quot;<a class="code" href="a00036.html">data.h</a>&quot;</span>
<a name="l00038"></a>00038 <span class="preprocessor">#include &quot;<a class="code" href="a00037.html">debug.h</a>&quot;</span>
<a name="l00039"></a>00039 <span class="preprocessor">#include &quot;<a class="code" href="a00040.html">handlers.h</a>&quot;</span>
<a name="l00040"></a>00040 <span class="preprocessor">#include &quot;<a class="code" href="a00031.html">click.h</a>&quot;</span>
<a name="l00041"></a>00041 <span class="preprocessor">#include &quot;<a class="code" href="a00041.html">i3.h</a>&quot;</span>
<a name="l00042"></a>00042 <span class="preprocessor">#include &quot;<a class="code" href="a00043.html">layout.h</a>&quot;</span>
<a name="l00043"></a>00043 <span class="preprocessor">#include &quot;<a class="code" href="a00047.html">queue.h</a>&quot;</span>
<a name="l00044"></a>00044 <span class="preprocessor">#include &quot;<a class="code" href="a00051.html">table.h</a>&quot;</span>
<a name="l00045"></a>00045 <span class="preprocessor">#include &quot;<a class="code" href="a00052.html">util.h</a>&quot;</span>
<a name="l00046"></a>00046 <span class="preprocessor">#include &quot;<a class="code" href="a00054.html">xcb.h</a>&quot;</span>
<a name="l00047"></a>00047 <span class="preprocessor">#include &quot;<a class="code" href="a00048.html">randr.h</a>&quot;</span>
<a name="l00048"></a>00048 <span class="preprocessor">#include &quot;<a class="code" href="a00055.html">xinerama.h</a>&quot;</span>
<a name="l00049"></a>00049 <span class="preprocessor">#include &quot;<a class="code" href="a00046.html">manage.h</a>&quot;</span>
<a name="l00050"></a>00050 <span class="preprocessor">#include &quot;<a class="code" href="a00042.html">ipc.h</a>&quot;</span>
<a name="l00051"></a>00051 <span class="preprocessor">#include &quot;<a class="code" href="a00044.html">log.h</a>&quot;</span>
<a name="l00052"></a>00052 <span class="preprocessor">#include &quot;<a class="code" href="a00050.html">sighandler.h</a>&quot;</span>
<a name="l00053"></a>00053 
<a name="l00054"></a><a class="code" href="a00071.html#ab7a200a5f990dc2deaae492aa7b57711">00054</a> <span class="keyword">static</span> <span class="keywordtype">int</span> <a class="code" href="a00071.html#ab7a200a5f990dc2deaae492aa7b57711">xkb_event_base</a>;
<a name="l00055"></a>00055 
<a name="l00056"></a><a class="code" href="a00041.html#a2590f55d5727c7d1cd01ebe7fd94a05d">00056</a> <span class="keywordtype">int</span> <a class="code" href="a00071.html#a2590f55d5727c7d1cd01ebe7fd94a05d">xkb_current_group</a>;
<a name="l00057"></a>00057 
<a name="l00058"></a><a class="code" href="a00041.html#ada13c42121d64521629e06e7a5e1db16">00058</a> xcb_connection_t *<a class="code" href="a00071.html#ada13c42121d64521629e06e7a5e1db16">global_conn</a>;
<a name="l00059"></a>00059 
<a name="l00060"></a>00060 <span class="comment">/* This is the path to i3, copied from argv[0] when starting up */</span>
<a name="l00061"></a><a class="code" href="a00041.html#adff3468c46bf36c35842552ad6cd220d">00061</a> <span class="keywordtype">char</span> **<a class="code" href="a00071.html#adff3468c46bf36c35842552ad6cd220d">start_argv</a>;
<a name="l00062"></a>00062 
<a name="l00063"></a>00063 <span class="comment">/* This is our connection to X11 for use with XKB */</span>
<a name="l00064"></a><a class="code" href="a00041.html#a3401bcd302be580b0500474e75726538">00064</a> Display *<a class="code" href="a00071.html#a3401bcd302be580b0500474e75726538">xkbdpy</a>;
<a name="l00065"></a>00065 
<a name="l00066"></a><a class="code" href="a00041.html#a5cc0138ae2cf3bbb63a7cae907620797">00066</a> xcb_key_symbols_t *<a class="code" href="a00071.html#a5cc0138ae2cf3bbb63a7cae907620797">keysyms</a>;
<a name="l00067"></a>00067 
<a name="l00068"></a>00068 <span class="comment">/* The list of key bindings */</span>
<a name="l00069"></a><a class="code" href="a00071.html#afe67646b6ee7ae51b130a59354fe7f49">00069</a> <span class="keyword">struct </span>bindings_head *<a class="code" href="a00071.html#afe67646b6ee7ae51b130a59354fe7f49">bindings</a>;
<a name="l00070"></a>00070 
<a name="l00071"></a>00071 <span class="comment">/* The list of exec-lines */</span>
<a name="l00072"></a><a class="code" href="a00071.html#adc8cf28482f0bbe29f8bdcba0e32d16f">00072</a> <span class="keyword">struct </span>autostarts_head <a class="code" href="a00071.html#adc8cf28482f0bbe29f8bdcba0e32d16f">autostarts</a> = <a class="code" href="a00047.html#ac269df7d4126ed9885156cbad2cbf8af">TAILQ_HEAD_INITIALIZER</a>(<a class="code" href="a00071.html#adc8cf28482f0bbe29f8bdcba0e32d16f">autostarts</a>);
<a name="l00073"></a>00073 
<a name="l00074"></a>00074 <span class="comment">/* The list of assignments */</span>
<a name="l00075"></a><a class="code" href="a00071.html#af36d2f2cbc5487cf0e9e2d60165b3e89">00075</a> <span class="keyword">struct </span>assignments_head <a class="code" href="a00071.html#af36d2f2cbc5487cf0e9e2d60165b3e89">assignments</a> = <a class="code" href="a00047.html#ac269df7d4126ed9885156cbad2cbf8af">TAILQ_HEAD_INITIALIZER</a>(<a class="code" href="a00071.html#af36d2f2cbc5487cf0e9e2d60165b3e89">assignments</a>);
<a name="l00076"></a>00076 
<a name="l00077"></a>00077 <span class="comment">/* This is a list of Stack_Windows, global, for easier/faster access on expose events */</span>
<a name="l00078"></a><a class="code" href="a00071.html#ac38e5cddf6395c52d3755d7b368e4a2b">00078</a> <span class="keyword">struct </span>stack_wins_head <a class="code" href="a00071.html#ac38e5cddf6395c52d3755d7b368e4a2b">stack_wins</a> = <a class="code" href="a00047.html#a9ae2aca3d46e62be4cb1408bd946ef15">SLIST_HEAD_INITIALIZER</a>(<a class="code" href="a00071.html#ac38e5cddf6395c52d3755d7b368e4a2b">stack_wins</a>);
<a name="l00079"></a>00079 
<a name="l00080"></a>00080 <span class="comment">/* The event handlers need to be global because they are accessed by our custom event handler</span>
<a name="l00081"></a>00081 <span class="comment">   in handle_button_press(), needed for graphical resizing */</span>
<a name="l00082"></a><a class="code" href="a00041.html#a123feed3140395e51010f45a3268464c">00082</a> xcb_event_handlers_t <a class="code" href="a00071.html#a123feed3140395e51010f45a3268464c">evenths</a>;
<a name="l00083"></a><a class="code" href="a00041.html#a327a6e1e08087496e9cb60b9e6f2a499">00083</a> xcb_atom_t <a class="code" href="a00071.html#a327a6e1e08087496e9cb60b9e6f2a499">atoms</a>[<a class="code" href="a00041.html#afe7f1cb6978a57f18167c0c7c7db4b12">NUM_ATOMS</a>];
<a name="l00084"></a>00084 
<a name="l00085"></a><a class="code" href="a00041.html#a768f07da9e11ab88732a5c550ff49257">00085</a> xcb_window_t <a class="code" href="a00071.html#a768f07da9e11ab88732a5c550ff49257">root</a>;
<a name="l00086"></a><a class="code" href="a00071.html#a59ff745efdee354cf2bc3dd370fec282">00086</a> <span class="keywordtype">int</span> <a class="code" href="a00071.html#a59ff745efdee354cf2bc3dd370fec282">num_screens</a> = 0;
<a name="l00087"></a>00087 
<a name="l00088"></a>00088 <span class="comment">/* The depth of the root screen (used e.g. for creating new pixmaps later) */</span>
<a name="l00089"></a><a class="code" href="a00041.html#a5cc2471a026cd3d2a8800e8ab2c9dcb7">00089</a> uint8_t <a class="code" href="a00071.html#a5cc2471a026cd3d2a8800e8ab2c9dcb7">root_depth</a>;
<a name="l00090"></a>00090 
<a name="l00091"></a>00091 <span class="comment">/* We hope that XKB is supported and set this to false */</span>
<a name="l00092"></a><a class="code" href="a00041.html#a213753c490c48df1df94aba1d4840eee">00092</a> <span class="keywordtype">bool</span> <a class="code" href="a00071.html#a213753c490c48df1df94aba1d4840eee">xkb_supported</a> = <span class="keyword">true</span>;
<a name="l00093"></a>00093 
<a name="l00094"></a>00094 <span class="comment">/*</span>
<a name="l00095"></a>00095 <span class="comment"> * This callback is only a dummy, see xcb_prepare_cb and xcb_check_cb.</span>
<a name="l00096"></a>00096 <span class="comment"> * See also man libev(3): &quot;ev_prepare&quot; and &quot;ev_check&quot; - customise your event loop</span>
<a name="l00097"></a>00097 <span class="comment"> *</span>
<a name="l00098"></a>00098 <span class="comment"> */</span>
<a name="l00099"></a><a class="code" href="a00071.html#a3afd076b2b7a6629dbdd5ca39bc97e14">00099</a> <span class="keyword">static</span> <span class="keywordtype">void</span> <a class="code" href="a00071.html#a3afd076b2b7a6629dbdd5ca39bc97e14">xcb_got_event</a>(EV_P_ <span class="keyword">struct</span> ev_io *w, <span class="keywordtype">int</span> revents) {
<a name="l00100"></a>00100         <span class="comment">/* empty, because xcb_prepare_cb and xcb_check_cb are used */</span>
<a name="l00101"></a>00101 }
<a name="l00102"></a>00102 
<a name="l00103"></a>00103 <span class="comment">/*</span>
<a name="l00104"></a>00104 <span class="comment"> * Flush before blocking (and waiting for new events)</span>
<a name="l00105"></a>00105 <span class="comment"> *</span>
<a name="l00106"></a>00106 <span class="comment"> */</span>
<a name="l00107"></a><a class="code" href="a00071.html#af056ab78448062575ad541c74acf424f">00107</a> <span class="keyword">static</span> <span class="keywordtype">void</span> <a class="code" href="a00071.html#af056ab78448062575ad541c74acf424f">xcb_prepare_cb</a>(EV_P_ ev_prepare *w, <span class="keywordtype">int</span> revents) {
<a name="l00108"></a>00108         xcb_flush(<a class="code" href="a00071.html#a123feed3140395e51010f45a3268464c">evenths</a>.c);
<a name="l00109"></a>00109 }
<a name="l00110"></a>00110 
<a name="l00111"></a>00111 <span class="comment">/*</span>
<a name="l00112"></a>00112 <span class="comment"> * Instead of polling the X connection socket we leave this to</span>
<a name="l00113"></a>00113 <span class="comment"> * xcb_poll_for_event() which knows better than we can ever know.</span>
<a name="l00114"></a>00114 <span class="comment"> *</span>
<a name="l00115"></a>00115 <span class="comment"> */</span>
<a name="l00116"></a><a class="code" href="a00071.html#ae803eb28e01465a23d3106d041d20a35">00116</a> <span class="keyword">static</span> <span class="keywordtype">void</span> <a class="code" href="a00071.html#ae803eb28e01465a23d3106d041d20a35">xcb_check_cb</a>(EV_P_ ev_check *w, <span class="keywordtype">int</span> revents) {
<a name="l00117"></a>00117         xcb_generic_event_t *event;
<a name="l00118"></a>00118 
<a name="l00119"></a>00119         <span class="keywordflow">while</span> ((event = xcb_poll_for_event(<a class="code" href="a00071.html#a123feed3140395e51010f45a3268464c">evenths</a>.c)) != NULL) {
<a name="l00120"></a>00120                 xcb_event_handle(&amp;<a class="code" href="a00071.html#a123feed3140395e51010f45a3268464c">evenths</a>, event);
<a name="l00121"></a>00121                 free(event);
<a name="l00122"></a>00122         }
<a name="l00123"></a>00123 }
<a name="l00124"></a>00124 
<a name="l00125"></a>00125 <span class="comment">/*</span>
<a name="l00126"></a>00126 <span class="comment"> * When using xmodmap to change the keyboard mapping, this event</span>
<a name="l00127"></a>00127 <span class="comment"> * is only sent via XKB. Therefore, we need this special handler.</span>
<a name="l00128"></a>00128 <span class="comment"> *</span>
<a name="l00129"></a>00129 <span class="comment"> */</span>
<a name="l00130"></a><a class="code" href="a00071.html#a9dee8ad840a7178248adce10de9f168a">00130</a> <span class="keyword">static</span> <span class="keywordtype">void</span> <a class="code" href="a00071.html#a9dee8ad840a7178248adce10de9f168a">xkb_got_event</a>(EV_P_ <span class="keyword">struct</span> ev_io *w, <span class="keywordtype">int</span> revents) {
<a name="l00131"></a>00131         <a class="code" href="a00044.html#a287e239c800086178591f5e53f5bb82c">DLOG</a>(<span class="stringliteral">&quot;Handling XKB event\n&quot;</span>);
<a name="l00132"></a>00132         XkbEvent ev;
<a name="l00133"></a>00133 
<a name="l00134"></a>00134         <span class="comment">/* When using xmodmap, every change (!) gets an own event.</span>
<a name="l00135"></a>00135 <span class="comment">         * Therefore, we just read all events and only handle the</span>
<a name="l00136"></a>00136 <span class="comment">         * mapping_notify once. */</span>
<a name="l00137"></a>00137         <span class="keywordtype">bool</span> mapping_changed = <span class="keyword">false</span>;
<a name="l00138"></a>00138         <span class="keywordflow">while</span> (XPending(<a class="code" href="a00071.html#a3401bcd302be580b0500474e75726538">xkbdpy</a>)) {
<a name="l00139"></a>00139                 XNextEvent(<a class="code" href="a00071.html#a3401bcd302be580b0500474e75726538">xkbdpy</a>, (XEvent*)&amp;ev);
<a name="l00140"></a>00140                 <span class="comment">/* While we should never receive a non-XKB event,</span>
<a name="l00141"></a>00141 <span class="comment">                 * better do sanity checking */</span>
<a name="l00142"></a>00142                 <span class="keywordflow">if</span> (ev.type != <a class="code" href="a00071.html#ab7a200a5f990dc2deaae492aa7b57711">xkb_event_base</a>)
<a name="l00143"></a>00143                         <span class="keywordflow">continue</span>;
<a name="l00144"></a>00144 
<a name="l00145"></a>00145                 <span class="keywordflow">if</span> (ev.any.xkb_type == XkbMapNotify) {
<a name="l00146"></a>00146                         mapping_changed = <span class="keyword">true</span>;
<a name="l00147"></a>00147                         <span class="keywordflow">continue</span>;
<a name="l00148"></a>00148                 }
<a name="l00149"></a>00149 
<a name="l00150"></a>00150                 <span class="keywordflow">if</span> (ev.any.xkb_type != XkbStateNotify) {
<a name="l00151"></a>00151                         <a class="code" href="a00044.html#a6828c68e0feb4b7fdfe0fc3ba9f3038b">ELOG</a>(<span class="stringliteral">&quot;Unknown XKB event received (type %d)\n&quot;</span>, ev.any.xkb_type);
<a name="l00152"></a>00152                         <span class="keywordflow">continue</span>;
<a name="l00153"></a>00153                 }
<a name="l00154"></a>00154 
<a name="l00155"></a>00155                 <span class="comment">/* See The XKB Extension: Library Specification, section 14.1 */</span>
<a name="l00156"></a>00156                 <span class="comment">/* We check if the current group (each group contains</span>
<a name="l00157"></a>00157 <span class="comment">                 * two levels) has been changed. Mode_switch activates</span>
<a name="l00158"></a>00158 <span class="comment">                 * group XkbGroup2Index */</span>
<a name="l00159"></a>00159                 <span class="keywordflow">if</span> (<a class="code" href="a00071.html#a2590f55d5727c7d1cd01ebe7fd94a05d">xkb_current_group</a> == ev.state.group)
<a name="l00160"></a>00160                         <span class="keywordflow">continue</span>;
<a name="l00161"></a>00161 
<a name="l00162"></a>00162                 <a class="code" href="a00071.html#a2590f55d5727c7d1cd01ebe7fd94a05d">xkb_current_group</a> = ev.state.group;
<a name="l00163"></a>00163 
<a name="l00164"></a>00164                 <span class="keywordflow">if</span> (ev.state.group == XkbGroup2Index) {
<a name="l00165"></a>00165                         <a class="code" href="a00044.html#a287e239c800086178591f5e53f5bb82c">DLOG</a>(<span class="stringliteral">&quot;Mode_switch enabled\n&quot;</span>);
<a name="l00166"></a>00166                         <a class="code" href="a00062.html#a1741cf749eb2243cca453355d3f6879b" title="Grab the bound keys (tell X to send us keypress events for those keycodes).">grab_all_keys</a>(<a class="code" href="a00071.html#ada13c42121d64521629e06e7a5e1db16">global_conn</a>, <span class="keyword">true</span>);
<a name="l00167"></a>00167                 }
<a name="l00168"></a>00168 
<a name="l00169"></a>00169                 <span class="keywordflow">if</span> (ev.state.group == XkbGroup1Index) {
<a name="l00170"></a>00170                         <a class="code" href="a00044.html#a287e239c800086178591f5e53f5bb82c">DLOG</a>(<span class="stringliteral">&quot;Mode_switch disabled\n&quot;</span>);
<a name="l00171"></a>00171                         <a class="code" href="a00062.html#afa95dc10a37decc54e9a376d0d462048" title="Ungrabs all keys, to be called before re-grabbing the keys because of a mapping_notify...">ungrab_all_keys</a>(<a class="code" href="a00071.html#ada13c42121d64521629e06e7a5e1db16">global_conn</a>);
<a name="l00172"></a>00172                         <a class="code" href="a00062.html#a1741cf749eb2243cca453355d3f6879b" title="Grab the bound keys (tell X to send us keypress events for those keycodes).">grab_all_keys</a>(<a class="code" href="a00071.html#ada13c42121d64521629e06e7a5e1db16">global_conn</a>, <span class="keyword">false</span>);
<a name="l00173"></a>00173                 }
<a name="l00174"></a>00174         }
<a name="l00175"></a>00175 
<a name="l00176"></a>00176         <span class="keywordflow">if</span> (!mapping_changed)
<a name="l00177"></a>00177                 <span class="keywordflow">return</span>;
<a name="l00178"></a>00178 
<a name="l00179"></a>00179         <a class="code" href="a00044.html#a287e239c800086178591f5e53f5bb82c">DLOG</a>(<span class="stringliteral">&quot;Keyboard mapping changed, updating keybindings\n&quot;</span>);
<a name="l00180"></a>00180         xcb_key_symbols_free(<a class="code" href="a00071.html#a5cc0138ae2cf3bbb63a7cae907620797">keysyms</a>);
<a name="l00181"></a>00181         <a class="code" href="a00071.html#a5cc0138ae2cf3bbb63a7cae907620797">keysyms</a> = xcb_key_symbols_alloc(<a class="code" href="a00071.html#ada13c42121d64521629e06e7a5e1db16">global_conn</a>);
<a name="l00182"></a>00182 
<a name="l00183"></a>00183         <a class="code" href="a00079.html#aeae86e9fc76e08fd43f142de4d11bba0" title="Finds out which modifier mask is the one for numlock, as the user may change this...">xcb_get_numlock_mask</a>(<a class="code" href="a00071.html#ada13c42121d64521629e06e7a5e1db16">global_conn</a>);
<a name="l00184"></a>00184 
<a name="l00185"></a>00185         <a class="code" href="a00062.html#afa95dc10a37decc54e9a376d0d462048" title="Ungrabs all keys, to be called before re-grabbing the keys because of a mapping_notify...">ungrab_all_keys</a>(<a class="code" href="a00071.html#ada13c42121d64521629e06e7a5e1db16">global_conn</a>);
<a name="l00186"></a>00186         <a class="code" href="a00044.html#a287e239c800086178591f5e53f5bb82c">DLOG</a>(<span class="stringliteral">&quot;Re-grabbing...\n&quot;</span>);
<a name="l00187"></a>00187         <a class="code" href="a00062.html#a0ee8ffa5c11aeb96126b36171da84adc" title="Translates keysymbols to keycodes for all bindings which use keysyms.">translate_keysyms</a>();
<a name="l00188"></a>00188         <a class="code" href="a00062.html#a1741cf749eb2243cca453355d3f6879b" title="Grab the bound keys (tell X to send us keypress events for those keycodes).">grab_all_keys</a>(<a class="code" href="a00071.html#ada13c42121d64521629e06e7a5e1db16">global_conn</a>, (<a class="code" href="a00071.html#a2590f55d5727c7d1cd01ebe7fd94a05d">xkb_current_group</a> == XkbGroup2Index));
<a name="l00189"></a>00189         <a class="code" href="a00044.html#a287e239c800086178591f5e53f5bb82c">DLOG</a>(<span class="stringliteral">&quot;Done\n&quot;</span>);
<a name="l00190"></a>00190 }
<a name="l00191"></a>00191 
<a name="l00192"></a>00192 
<a name="l00193"></a><a class="code" href="a00071.html#a7f567e72b4713406998c6192bb2a10e7">00193</a> <span class="keywordtype">int</span> <a class="code" href="a00071.html#a7f567e72b4713406998c6192bb2a10e7">main</a>(<span class="keywordtype">int</span> argc, <span class="keywordtype">char</span> *argv[], <span class="keywordtype">char</span> *env[]) {
<a name="l00194"></a>00194         <span class="keywordtype">int</span> i, screens, opt;
<a name="l00195"></a>00195         <span class="keywordtype">char</span> *override_configpath = NULL;
<a name="l00196"></a>00196         <span class="keywordtype">bool</span> autostart = <span class="keyword">true</span>;
<a name="l00197"></a>00197         <span class="keywordtype">bool</span> only_check_config = <span class="keyword">false</span>;
<a name="l00198"></a>00198         <span class="keywordtype">bool</span> force_xinerama = <span class="keyword">false</span>;
<a name="l00199"></a>00199         xcb_connection_t *conn;
<a name="l00200"></a>00200         xcb_property_handlers_t prophs;
<a name="l00201"></a>00201         xcb_intern_atom_cookie_t atom_cookies[<a class="code" href="a00041.html#afe7f1cb6978a57f18167c0c7c7db4b12">NUM_ATOMS</a>];
<a name="l00202"></a>00202         <span class="keyword">static</span> <span class="keyword">struct </span>option long_options[] = {
<a name="l00203"></a>00203                 {<span class="stringliteral">&quot;no-autostart&quot;</span>, no_argument, 0, <span class="charliteral">&#39;a&#39;</span>},
<a name="l00204"></a>00204                 {<span class="stringliteral">&quot;config&quot;</span>, required_argument, 0, <span class="charliteral">&#39;c&#39;</span>},
<a name="l00205"></a>00205                 {<span class="stringliteral">&quot;version&quot;</span>, no_argument, 0, <span class="charliteral">&#39;v&#39;</span>},
<a name="l00206"></a>00206                 {<span class="stringliteral">&quot;help&quot;</span>, no_argument, 0, <span class="charliteral">&#39;h&#39;</span>},
<a name="l00207"></a>00207                 {<span class="stringliteral">&quot;force-xinerama&quot;</span>, no_argument, 0, 0},
<a name="l00208"></a>00208                 {0, 0, 0, 0}
<a name="l00209"></a>00209         };
<a name="l00210"></a>00210         <span class="keywordtype">int</span> option_index = 0;
<a name="l00211"></a>00211 
<a name="l00212"></a>00212         setlocale(LC_ALL, <span class="stringliteral">&quot;&quot;</span>);
<a name="l00213"></a>00213 
<a name="l00214"></a>00214         <span class="comment">/* Disable output buffering to make redirects in .xsession actually useful for debugging */</span>
<a name="l00215"></a>00215         <span class="keywordflow">if</span> (!isatty(fileno(stdout)))
<a name="l00216"></a>00216                 setbuf(stdout, NULL);
<a name="l00217"></a>00217 
<a name="l00218"></a>00218         <a class="code" href="a00071.html#adff3468c46bf36c35842552ad6cd220d">start_argv</a> = argv;
<a name="l00219"></a>00219 
<a name="l00220"></a>00220         <span class="keywordflow">while</span> ((opt = getopt_long(argc, argv, <span class="stringliteral">&quot;c:Cvahld:V&quot;</span>, long_options, &amp;option_index)) != -1) {
<a name="l00221"></a>00221                 <span class="keywordflow">switch</span> (opt) {
<a name="l00222"></a>00222                         <span class="keywordflow">case</span> <span class="charliteral">&#39;a&#39;</span>:
<a name="l00223"></a>00223                                 <a class="code" href="a00044.html#a388edf12256bf73c3a8ee9734c3bd841" title="#__VA_ARGS__ means: leave out __VA_ARGS__ completely if it is empty, that is, delete...">LOG</a>(<span class="stringliteral">&quot;Autostart disabled using -a\n&quot;</span>);
<a name="l00224"></a>00224                                 autostart = <span class="keyword">false</span>;
<a name="l00225"></a>00225                                 <span class="keywordflow">break</span>;
<a name="l00226"></a>00226                         <span class="keywordflow">case</span> <span class="charliteral">&#39;c&#39;</span>:
<a name="l00227"></a>00227                                 override_configpath = <a class="code" href="a00077.html#a11822d1f4b182be3fa03d2a5af536e1a" title="Safe-wrapper around strdup which exits if malloc returns NULL (meaning that there...">sstrdup</a>(optarg);
<a name="l00228"></a>00228                                 <span class="keywordflow">break</span>;
<a name="l00229"></a>00229                         <span class="keywordflow">case</span> <span class="charliteral">&#39;C&#39;</span>:
<a name="l00230"></a>00230                                 <a class="code" href="a00044.html#a388edf12256bf73c3a8ee9734c3bd841" title="#__VA_ARGS__ means: leave out __VA_ARGS__ completely if it is empty, that is, delete...">LOG</a>(<span class="stringliteral">&quot;Checking configuration file only (-C)\n&quot;</span>);
<a name="l00231"></a>00231                                 only_check_config = <span class="keyword">true</span>;
<a name="l00232"></a>00232                                 <span class="keywordflow">break</span>;
<a name="l00233"></a>00233                         <span class="keywordflow">case</span> <span class="charliteral">&#39;v&#39;</span>:
<a name="l00234"></a>00234                                 printf(<span class="stringliteral">&quot;i3 version &quot;</span> I3_VERSION <span class="stringliteral">&quot; © 2009-2010 Michael Stapelberg and contributors\n&quot;</span>);
<a name="l00235"></a>00235                                 exit(EXIT_SUCCESS);
<a name="l00236"></a>00236                         <span class="keywordflow">case</span> <span class="charliteral">&#39;V&#39;</span>:
<a name="l00237"></a>00237                                 <a class="code" href="a00070.html#a9aeb8f383a036722d9213b750e90703d" title="Set verbosity of i3.">set_verbosity</a>(<span class="keyword">true</span>);
<a name="l00238"></a>00238                                 <span class="keywordflow">break</span>;
<a name="l00239"></a>00239                         <span class="keywordflow">case</span> <span class="charliteral">&#39;d&#39;</span>:
<a name="l00240"></a>00240                                 <a class="code" href="a00044.html#a388edf12256bf73c3a8ee9734c3bd841" title="#__VA_ARGS__ means: leave out __VA_ARGS__ completely if it is empty, that is, delete...">LOG</a>(<span class="stringliteral">&quot;Enabling debug loglevel %s\n&quot;</span>, optarg);
<a name="l00241"></a>00241                                 <a class="code" href="a00070.html#a71ad89f7f5c5c75b215dfa26a9c1bc43" title="Enables the given loglevel.">add_loglevel</a>(optarg);
<a name="l00242"></a>00242                                 <span class="keywordflow">break</span>;
<a name="l00243"></a>00243                         <span class="keywordflow">case</span> <span class="charliteral">&#39;l&#39;</span>:
<a name="l00244"></a>00244                                 <span class="comment">/* DEPRECATED, ignored for the next 3 versions (3.e, 3.f, 3.g) */</span>
<a name="l00245"></a>00245                                 <span class="keywordflow">break</span>;
<a name="l00246"></a>00246                         <span class="keywordflow">case</span> 0:
<a name="l00247"></a>00247                                 <span class="keywordflow">if</span> (strcmp(long_options[option_index].name, <span class="stringliteral">&quot;force-xinerama&quot;</span>) == 0) {
<a name="l00248"></a>00248                                         force_xinerama = <span class="keyword">true</span>;
<a name="l00249"></a>00249                                         <a class="code" href="a00044.html#a6828c68e0feb4b7fdfe0fc3ba9f3038b">ELOG</a>(<span class="stringliteral">&quot;Using Xinerama instead of RandR. This option should be &quot;</span>
<a name="l00250"></a>00250                                              <span class="stringliteral">&quot;avoided at all cost because it does not refresh the list &quot;</span>
<a name="l00251"></a>00251                                              <span class="stringliteral">&quot;of screens, so you cannot configure displays at runtime. &quot;</span>
<a name="l00252"></a>00252                                              <span class="stringliteral">&quot;Please check if your driver really does not support RandR &quot;</span>
<a name="l00253"></a>00253                                              <span class="stringliteral">&quot;and disable this option as soon as you can.\n&quot;</span>);
<a name="l00254"></a>00254                                         <span class="keywordflow">break</span>;
<a name="l00255"></a>00255                                 }
<a name="l00256"></a>00256                                 <span class="comment">/* fall-through */</span>
<a name="l00257"></a>00257                         <span class="keywordflow">default</span>:
<a name="l00258"></a>00258                                 fprintf(stderr, <span class="stringliteral">&quot;Usage: %s [-c configfile] [-d loglevel] [-a] [-v] [-V] [-C]\n&quot;</span>, argv[0]);
<a name="l00259"></a>00259                                 fprintf(stderr, <span class="stringliteral">&quot;\n&quot;</span>);
<a name="l00260"></a>00260                                 fprintf(stderr, <span class="stringliteral">&quot;-a: disable autostart\n&quot;</span>);
<a name="l00261"></a>00261                                 fprintf(stderr, <span class="stringliteral">&quot;-v: display version and exit\n&quot;</span>);
<a name="l00262"></a>00262                                 fprintf(stderr, <span class="stringliteral">&quot;-V: enable verbose mode\n&quot;</span>);
<a name="l00263"></a>00263                                 fprintf(stderr, <span class="stringliteral">&quot;-d &lt;loglevel&gt;: enable debug loglevel &lt;loglevel&gt;\n&quot;</span>);
<a name="l00264"></a>00264                                 fprintf(stderr, <span class="stringliteral">&quot;-c &lt;configfile&gt;: use the provided configfile instead\n&quot;</span>);
<a name="l00265"></a>00265                                 fprintf(stderr, <span class="stringliteral">&quot;-C: check configuration file and exit\n&quot;</span>);
<a name="l00266"></a>00266                                 fprintf(stderr, <span class="stringliteral">&quot;--force-xinerama: Use Xinerama instead of RandR. This &quot;</span>
<a name="l00267"></a>00267                                                 <span class="stringliteral">&quot;option should only be used if you are stuck with the &quot;</span>
<a name="l00268"></a>00268                                                 <span class="stringliteral">&quot;nvidia closed source driver which does not support RandR.\n&quot;</span>);
<a name="l00269"></a>00269                                 exit(EXIT_FAILURE);
<a name="l00270"></a>00270                 }
<a name="l00271"></a>00271         }
<a name="l00272"></a>00272 
<a name="l00273"></a>00273         <a class="code" href="a00044.html#a388edf12256bf73c3a8ee9734c3bd841" title="#__VA_ARGS__ means: leave out __VA_ARGS__ completely if it is empty, that is, delete...">LOG</a>(<span class="stringliteral">&quot;i3 version &quot;</span> I3_VERSION <span class="stringliteral">&quot; starting\n&quot;</span>);
<a name="l00274"></a>00274 
<a name="l00275"></a>00275         <span class="comment">/* Initialize the table data structures for each workspace */</span>
<a name="l00276"></a>00276         <a class="code" href="a00076.html#af025cd3b8bcee08bf8f89ae8c17d5f69" title="Initialize table.">init_table</a>();
<a name="l00277"></a>00277 
<a name="l00278"></a>00278         memset(&amp;<a class="code" href="a00071.html#a123feed3140395e51010f45a3268464c">evenths</a>, 0, <span class="keyword">sizeof</span>(xcb_event_handlers_t));
<a name="l00279"></a>00279         memset(&amp;prophs, 0, <span class="keyword">sizeof</span>(xcb_property_handlers_t));
<a name="l00280"></a>00280 
<a name="l00281"></a>00281         conn = <a class="code" href="a00071.html#ada13c42121d64521629e06e7a5e1db16">global_conn</a> = xcb_connect(NULL, &amp;screens);
<a name="l00282"></a>00282 
<a name="l00283"></a>00283         <span class="keywordflow">if</span> (xcb_connection_has_error(conn))
<a name="l00284"></a>00284                 <a class="code" href="a00052.html#a0b2164ee75646f16a7388a36e6800c35">die</a>(<span class="stringliteral">&quot;Cannot open display\n&quot;</span>);
<a name="l00285"></a>00285 
<a name="l00286"></a>00286         <a class="code" href="a00062.html#a19bff8205cd2bd9492b5f95076dfa3a0" title="Reads the configuration from ~/.i3/config or /etc/i3/config if not found.">load_configuration</a>(conn, override_configpath, <span class="keyword">false</span>);
<a name="l00287"></a>00287         <span class="keywordflow">if</span> (only_check_config) {
<a name="l00288"></a>00288                 <a class="code" href="a00044.html#a388edf12256bf73c3a8ee9734c3bd841" title="#__VA_ARGS__ means: leave out __VA_ARGS__ completely if it is empty, that is, delete...">LOG</a>(<span class="stringliteral">&quot;Done checking configuration file. Exiting.\n&quot;</span>);
<a name="l00289"></a>00289                 exit(0);
<a name="l00290"></a>00290         }
<a name="l00291"></a>00291 
<a name="l00292"></a>00292         <span class="comment">/* Create the initial container on the first workspace. This used to</span>
<a name="l00293"></a>00293 <span class="comment">         * be part of init_table, but since it possibly requires an X</span>
<a name="l00294"></a>00294 <span class="comment">         * connection and a loaded configuration (default mode for new</span>
<a name="l00295"></a>00295 <span class="comment">         * containers may be stacking, which requires a new window to be</span>
<a name="l00296"></a>00296 <span class="comment">         * created), it had to be delayed. */</span>
<a name="l00297"></a>00297         <a class="code" href="a00076.html#ac58314a435fd187ce2ed416b9dc8019f" title="Add one column to the table.">expand_table_cols</a>(<a class="code" href="a00047.html#a7d6894360bd1c41e0e6f6d84998c1362">TAILQ_FIRST</a>(<a class="code" href="a00076.html#afb45f3a3a9c66c3e3a5e4d372ae24da7">workspaces</a>));
<a name="l00298"></a>00298         <a class="code" href="a00076.html#a8fb9ac616cc935e2fd54c6bcb6563df1" title="Add one row to the table.">expand_table_rows</a>(<a class="code" href="a00047.html#a7d6894360bd1c41e0e6f6d84998c1362">TAILQ_FIRST</a>(<a class="code" href="a00076.html#afb45f3a3a9c66c3e3a5e4d372ae24da7">workspaces</a>));
<a name="l00299"></a>00299 
<a name="l00300"></a>00300         <span class="comment">/* Place requests for the atoms we need as soon as possible */</span>
<a name="l00301"></a>00301 <span class="preprocessor">        #define REQUEST_ATOM(name) atom_cookies[name] = xcb_intern_atom(conn, 0, strlen(#name), #name);</span>
<a name="l00302"></a>00302 <span class="preprocessor"></span>
<a name="l00303"></a>00303         <a class="code" href="a00071.html#a868013b069440d8dff4c0554efbd10c6">REQUEST_ATOM</a>(<a class="code" href="a00054.html#a726ca809ffd3d67ab4b8476646f26635a02709e70342f55474db97400e435c636">_NET_SUPPORTED</a>);
<a name="l00304"></a>00304         <a class="code" href="a00071.html#a868013b069440d8dff4c0554efbd10c6">REQUEST_ATOM</a>(<a class="code" href="a00054.html#a726ca809ffd3d67ab4b8476646f26635accdb5c5ee0d74dfffda6f4324a9abff5">_NET_WM_STATE_FULLSCREEN</a>);
<a name="l00305"></a>00305         <a class="code" href="a00071.html#a868013b069440d8dff4c0554efbd10c6">REQUEST_ATOM</a>(<a class="code" href="a00054.html#a726ca809ffd3d67ab4b8476646f26635aabc07cc4cd1aea6087dc5763d82576cf">_NET_SUPPORTING_WM_CHECK</a>);
<a name="l00306"></a>00306         <a class="code" href="a00071.html#a868013b069440d8dff4c0554efbd10c6">REQUEST_ATOM</a>(<a class="code" href="a00054.html#a726ca809ffd3d67ab4b8476646f26635a1dedae1b3288478b95e08984bac0e951">_NET_WM_NAME</a>);
<a name="l00307"></a>00307         <a class="code" href="a00071.html#a868013b069440d8dff4c0554efbd10c6">REQUEST_ATOM</a>(<a class="code" href="a00054.html#a726ca809ffd3d67ab4b8476646f26635a555588bf6061a168cd7526a49dc4b0fa">_NET_WM_STATE</a>);
<a name="l00308"></a>00308         <a class="code" href="a00071.html#a868013b069440d8dff4c0554efbd10c6">REQUEST_ATOM</a>(<a class="code" href="a00054.html#a726ca809ffd3d67ab4b8476646f26635ad2b0847e09761bd2ad2b6482c51b07ca">_NET_WM_WINDOW_TYPE</a>);
<a name="l00309"></a>00309         <a class="code" href="a00071.html#a868013b069440d8dff4c0554efbd10c6">REQUEST_ATOM</a>(<a class="code" href="a00054.html#a726ca809ffd3d67ab4b8476646f26635a92d29c09b7c0af698c72325a0372126f">_NET_WM_DESKTOP</a>);
<a name="l00310"></a>00310         <a class="code" href="a00071.html#a868013b069440d8dff4c0554efbd10c6">REQUEST_ATOM</a>(<a class="code" href="a00054.html#a726ca809ffd3d67ab4b8476646f26635a2d1c4f653feb0746c9d55bddfa1f8946">_NET_WM_WINDOW_TYPE_DOCK</a>);
<a name="l00311"></a>00311         <a class="code" href="a00071.html#a868013b069440d8dff4c0554efbd10c6">REQUEST_ATOM</a>(<a class="code" href="a00054.html#a726ca809ffd3d67ab4b8476646f26635afc6c49b0d04427d54227a147e230fa6c">_NET_WM_WINDOW_TYPE_DIALOG</a>);
<a name="l00312"></a>00312         <a class="code" href="a00071.html#a868013b069440d8dff4c0554efbd10c6">REQUEST_ATOM</a>(<a class="code" href="a00054.html#a726ca809ffd3d67ab4b8476646f26635a2e553ea4ae93c2324801a40f52d7a70a">_NET_WM_WINDOW_TYPE_UTILITY</a>);
<a name="l00313"></a>00313         <a class="code" href="a00071.html#a868013b069440d8dff4c0554efbd10c6">REQUEST_ATOM</a>(<a class="code" href="a00054.html#a726ca809ffd3d67ab4b8476646f26635adc360a29b4d20ba8cd1c999f6077a843">_NET_WM_WINDOW_TYPE_TOOLBAR</a>);
<a name="l00314"></a>00314         <a class="code" href="a00071.html#a868013b069440d8dff4c0554efbd10c6">REQUEST_ATOM</a>(<a class="code" href="a00054.html#a726ca809ffd3d67ab4b8476646f26635a49555c0ebb81f76501d672c92857704a">_NET_WM_WINDOW_TYPE_SPLASH</a>);
<a name="l00315"></a>00315         <a class="code" href="a00071.html#a868013b069440d8dff4c0554efbd10c6">REQUEST_ATOM</a>(<a class="code" href="a00054.html#a726ca809ffd3d67ab4b8476646f26635a5171f3918252a26530d02d6a1716ca45">_NET_WM_STRUT_PARTIAL</a>);
<a name="l00316"></a>00316         <a class="code" href="a00071.html#a868013b069440d8dff4c0554efbd10c6">REQUEST_ATOM</a>(<a class="code" href="a00054.html#a726ca809ffd3d67ab4b8476646f26635a5d7366da3deea67253099a5c730d4297">WM_PROTOCOLS</a>);
<a name="l00317"></a>00317         <a class="code" href="a00071.html#a868013b069440d8dff4c0554efbd10c6">REQUEST_ATOM</a>(<a class="code" href="a00054.html#a726ca809ffd3d67ab4b8476646f26635a72e98f8036033fc3b9db52933dd749d0">WM_DELETE_WINDOW</a>);
<a name="l00318"></a>00318         <a class="code" href="a00071.html#a868013b069440d8dff4c0554efbd10c6">REQUEST_ATOM</a>(<a class="code" href="a00054.html#a726ca809ffd3d67ab4b8476646f26635aef8323bb1a48d3826fa5269e578b4a6a">UTF8_STRING</a>);
<a name="l00319"></a>00319         <a class="code" href="a00071.html#a868013b069440d8dff4c0554efbd10c6">REQUEST_ATOM</a>(<a class="code" href="a00054.html#a726ca809ffd3d67ab4b8476646f26635a5ce0f911fd3494577cce5417d7b7eea4">WM_STATE</a>);
<a name="l00320"></a>00320         <a class="code" href="a00071.html#a868013b069440d8dff4c0554efbd10c6">REQUEST_ATOM</a>(<a class="code" href="a00054.html#a726ca809ffd3d67ab4b8476646f26635a13d4dbc6987347bcc7c535570b4e6c2b">WM_CLIENT_LEADER</a>);
<a name="l00321"></a>00321         <a class="code" href="a00071.html#a868013b069440d8dff4c0554efbd10c6">REQUEST_ATOM</a>(<a class="code" href="a00054.html#a726ca809ffd3d67ab4b8476646f26635a7b3651a6efcb0970efc89dc301c91e5e">_NET_CURRENT_DESKTOP</a>);
<a name="l00322"></a>00322         <a class="code" href="a00071.html#a868013b069440d8dff4c0554efbd10c6">REQUEST_ATOM</a>(<a class="code" href="a00054.html#a726ca809ffd3d67ab4b8476646f26635ac34e05dfa966932f57aad3f572ed01f2">_NET_ACTIVE_WINDOW</a>);
<a name="l00323"></a>00323         <a class="code" href="a00071.html#a868013b069440d8dff4c0554efbd10c6">REQUEST_ATOM</a>(<a class="code" href="a00054.html#a726ca809ffd3d67ab4b8476646f26635a5258a6a20735e2ae242453ddaf60d157">_NET_WORKAREA</a>);
<a name="l00324"></a>00324 
<a name="l00325"></a>00325         <span class="comment">/* TODO: this has to be more beautiful somewhen */</span>
<a name="l00326"></a>00326         <span class="keywordtype">int</span> major, minor, error;
<a name="l00327"></a>00327 
<a name="l00328"></a>00328         major = XkbMajorVersion;
<a name="l00329"></a>00329         minor = XkbMinorVersion;
<a name="l00330"></a>00330 
<a name="l00331"></a>00331         <span class="keywordtype">int</span> errBase;
<a name="l00332"></a>00332 
<a name="l00333"></a>00333         <span class="keywordflow">if</span> ((<a class="code" href="a00071.html#a3401bcd302be580b0500474e75726538">xkbdpy</a> = XkbOpenDisplay(getenv(<span class="stringliteral">&quot;DISPLAY&quot;</span>), &amp;<a class="code" href="a00071.html#ab7a200a5f990dc2deaae492aa7b57711">xkb_event_base</a>, &amp;errBase, &amp;major, &amp;minor, &amp;error)) == NULL) {
<a name="l00334"></a>00334                 <a class="code" href="a00044.html#a6828c68e0feb4b7fdfe0fc3ba9f3038b">ELOG</a>(<span class="stringliteral">&quot;ERROR: XkbOpenDisplay() failed, disabling XKB support\n&quot;</span>);
<a name="l00335"></a>00335                 <a class="code" href="a00071.html#a213753c490c48df1df94aba1d4840eee">xkb_supported</a> = <span class="keyword">false</span>;
<a name="l00336"></a>00336         }
<a name="l00337"></a>00337 
<a name="l00338"></a>00338         <span class="keywordflow">if</span> (<a class="code" href="a00071.html#a213753c490c48df1df94aba1d4840eee">xkb_supported</a>) {
<a name="l00339"></a>00339                 <span class="keywordflow">if</span> (fcntl(ConnectionNumber(<a class="code" href="a00071.html#a3401bcd302be580b0500474e75726538">xkbdpy</a>), F_SETFD, FD_CLOEXEC) == -1) {
<a name="l00340"></a>00340                         fprintf(stderr, <span class="stringliteral">&quot;Could not set FD_CLOEXEC on xkbdpy\n&quot;</span>);
<a name="l00341"></a>00341                         <span class="keywordflow">return</span> 1;
<a name="l00342"></a>00342                 }
<a name="l00343"></a>00343 
<a name="l00344"></a>00344                 <span class="keywordtype">int</span> i1;
<a name="l00345"></a>00345                 <span class="keywordflow">if</span> (!XkbQueryExtension(<a class="code" href="a00071.html#a3401bcd302be580b0500474e75726538">xkbdpy</a>,&amp;i1,&amp;<a class="code" href="a00071.html#ab7a200a5f990dc2deaae492aa7b57711">xkb_event_base</a>,&amp;errBase,&amp;major,&amp;minor)) {
<a name="l00346"></a>00346                         fprintf(stderr, <span class="stringliteral">&quot;XKB not supported by X-server\n&quot;</span>);
<a name="l00347"></a>00347                         <span class="keywordflow">return</span> 1;
<a name="l00348"></a>00348                 }
<a name="l00349"></a>00349                 <span class="comment">/* end of ugliness */</span>
<a name="l00350"></a>00350 
<a name="l00351"></a>00351                 <span class="keywordflow">if</span> (!XkbSelectEvents(<a class="code" href="a00071.html#a3401bcd302be580b0500474e75726538">xkbdpy</a>, XkbUseCoreKbd,
<a name="l00352"></a>00352                                      XkbMapNotifyMask | XkbStateNotifyMask,
<a name="l00353"></a>00353                                      XkbMapNotifyMask | XkbStateNotifyMask)) {
<a name="l00354"></a>00354                         fprintf(stderr, <span class="stringliteral">&quot;Could not set XKB event mask\n&quot;</span>);
<a name="l00355"></a>00355                         <span class="keywordflow">return</span> 1;
<a name="l00356"></a>00356                 }
<a name="l00357"></a>00357         }
<a name="l00358"></a>00358 
<a name="l00359"></a>00359         <span class="comment">/* Initialize event loop using libev */</span>
<a name="l00360"></a>00360         <span class="keyword">struct </span>ev_loop *loop = ev_loop_new(0);
<a name="l00361"></a>00361         <span class="keywordflow">if</span> (loop == NULL)
<a name="l00362"></a>00362                 <a class="code" href="a00052.html#a0b2164ee75646f16a7388a36e6800c35">die</a>(<span class="stringliteral">&quot;Could not initialize libev. Bad LIBEV_FLAGS?\n&quot;</span>);
<a name="l00363"></a>00363 
<a name="l00364"></a>00364         <span class="keyword">struct </span>ev_io *xcb_watcher = <a class="code" href="a00077.html#ad475e1b898d9da9b2a8b92e3da51b3dd" title="Safe-wrapper around calloc which exits if malloc returns NULL (meaning that there...">scalloc</a>(<span class="keyword">sizeof</span>(<span class="keyword">struct</span> ev_io));
<a name="l00365"></a>00365         <span class="keyword">struct </span>ev_io *xkb = <a class="code" href="a00077.html#ad475e1b898d9da9b2a8b92e3da51b3dd" title="Safe-wrapper around calloc which exits if malloc returns NULL (meaning that there...">scalloc</a>(<span class="keyword">sizeof</span>(<span class="keyword">struct</span> ev_io));
<a name="l00366"></a>00366         <span class="keyword">struct </span>ev_check *xcb_check = <a class="code" href="a00077.html#ad475e1b898d9da9b2a8b92e3da51b3dd" title="Safe-wrapper around calloc which exits if malloc returns NULL (meaning that there...">scalloc</a>(<span class="keyword">sizeof</span>(<span class="keyword">struct</span> ev_check));
<a name="l00367"></a>00367         <span class="keyword">struct </span>ev_prepare *xcb_prepare = <a class="code" href="a00077.html#ad475e1b898d9da9b2a8b92e3da51b3dd" title="Safe-wrapper around calloc which exits if malloc returns NULL (meaning that there...">scalloc</a>(<span class="keyword">sizeof</span>(<span class="keyword">struct</span> ev_prepare));
<a name="l00368"></a>00368 
<a name="l00369"></a>00369         ev_io_init(xcb_watcher, <a class="code" href="a00071.html#a3afd076b2b7a6629dbdd5ca39bc97e14">xcb_got_event</a>, xcb_get_file_descriptor(conn), EV_READ);
<a name="l00370"></a>00370         ev_io_start(loop, xcb_watcher);
<a name="l00371"></a>00371 
<a name="l00372"></a>00372         <span class="keywordflow">if</span> (<a class="code" href="a00071.html#a213753c490c48df1df94aba1d4840eee">xkb_supported</a>) {
<a name="l00373"></a>00373                 ev_io_init(xkb, <a class="code" href="a00071.html#a9dee8ad840a7178248adce10de9f168a">xkb_got_event</a>, ConnectionNumber(<a class="code" href="a00071.html#a3401bcd302be580b0500474e75726538">xkbdpy</a>), EV_READ);
<a name="l00374"></a>00374                 ev_io_start(loop, xkb);
<a name="l00375"></a>00375 
<a name="l00376"></a>00376                 <span class="comment">/* Flush the buffer so that libev can properly get new events */</span>
<a name="l00377"></a>00377                 XFlush(<a class="code" href="a00071.html#a3401bcd302be580b0500474e75726538">xkbdpy</a>);
<a name="l00378"></a>00378         }
<a name="l00379"></a>00379 
<a name="l00380"></a>00380         ev_check_init(xcb_check, <a class="code" href="a00071.html#ae803eb28e01465a23d3106d041d20a35">xcb_check_cb</a>);
<a name="l00381"></a>00381         ev_check_start(loop, xcb_check);
<a name="l00382"></a>00382 
<a name="l00383"></a>00383         ev_prepare_init(xcb_prepare, <a class="code" href="a00071.html#af056ab78448062575ad541c74acf424f">xcb_prepare_cb</a>);
<a name="l00384"></a>00384         ev_prepare_start(loop, xcb_prepare);
<a name="l00385"></a>00385 
<a name="l00386"></a>00386         <span class="comment">/* Grab the server to delay any events until we enter the eventloop */</span>
<a name="l00387"></a>00387         xcb_grab_server(conn);
<a name="l00388"></a>00388 
<a name="l00389"></a>00389         xcb_event_handlers_init(conn, &amp;<a class="code" href="a00071.html#a123feed3140395e51010f45a3268464c">evenths</a>);
<a name="l00390"></a>00390 
<a name="l00391"></a>00391         <span class="comment">/* DEBUG: Trap all events and print them */</span>
<a name="l00392"></a>00392         <span class="keywordflow">for</span> (i = 2; i &lt; 128; ++i)
<a name="l00393"></a>00393                 xcb_event_set_handler(&amp;<a class="code" href="a00071.html#a123feed3140395e51010f45a3268464c">evenths</a>, i, <a class="code" href="a00064.html#a5f13dbbbc2fe5c143d138bba3b873b53">handle_event</a>, 0);
<a name="l00394"></a>00394 
<a name="l00395"></a>00395         <span class="keywordflow">for</span> (i = 0; i &lt; 256; ++i)
<a name="l00396"></a>00396                 xcb_event_set_error_handler(&amp;<a class="code" href="a00071.html#a123feed3140395e51010f45a3268464c">evenths</a>, i, (xcb_generic_error_handler_t)<a class="code" href="a00064.html#a5f13dbbbc2fe5c143d138bba3b873b53">handle_event</a>, 0);
<a name="l00397"></a>00397 
<a name="l00398"></a>00398         <span class="comment">/* Expose = an Application should redraw itself, in this case it’s our titlebars. */</span>
<a name="l00399"></a>00399         xcb_event_set_expose_handler(&amp;<a class="code" href="a00071.html#a123feed3140395e51010f45a3268464c">evenths</a>, <a class="code" href="a00067.html#aef74cebc820b8224d196fa6eb9c13ac4" title="Expose event means we should redraw our windows (= title bar).">handle_expose_event</a>, NULL);
<a name="l00400"></a>00400 
<a name="l00401"></a>00401         <span class="comment">/* Key presses are pretty obvious, I think */</span>
<a name="l00402"></a>00402         xcb_event_set_key_press_handler(&amp;<a class="code" href="a00071.html#a123feed3140395e51010f45a3268464c">evenths</a>, <a class="code" href="a00067.html#abcdedd21ed4dd7e762b2fb2ac49b6527" title="There was a key press.">handle_key_press</a>, NULL);
<a name="l00403"></a>00403 
<a name="l00404"></a>00404         <span class="comment">/* Enter window = user moved his mouse over the window */</span>
<a name="l00405"></a>00405         xcb_event_set_enter_notify_handler(&amp;<a class="code" href="a00071.html#a123feed3140395e51010f45a3268464c">evenths</a>, <a class="code" href="a00067.html#ade0bc204de173bdbeacb7b10b5631aec" title="When the user moves the mouse pointer onto a window, this callback gets called.">handle_enter_notify</a>, NULL);
<a name="l00406"></a>00406 
<a name="l00407"></a>00407         <span class="comment">/* Button press = user pushed a mouse button over one of our windows */</span>
<a name="l00408"></a>00408         xcb_event_set_button_press_handler(&amp;<a class="code" href="a00071.html#a123feed3140395e51010f45a3268464c">evenths</a>, <a class="code" href="a00059.html#ac97f2eddd5082f584d9370459628f503" title="Checks if the button press was on a stack window, handles focus setting and returns...">handle_button_press</a>, NULL);
<a name="l00409"></a>00409 
<a name="l00410"></a>00410         <span class="comment">/* Map notify = there is a new window */</span>
<a name="l00411"></a>00411         xcb_event_set_map_request_handler(&amp;<a class="code" href="a00071.html#a123feed3140395e51010f45a3268464c">evenths</a>, <a class="code" href="a00067.html#ae301f3f0db441a1c22a39e88989a96c3" title="A new window appeared on the screen (=was mapped), so let’s manage it.">handle_map_request</a>, &amp;prophs);
<a name="l00412"></a>00412 
<a name="l00413"></a>00413         <span class="comment">/* Unmap notify = window disappeared. When sent from a client, we don’t manage</span>
<a name="l00414"></a>00414 <span class="comment">           it any longer. Usually, the client destroys the window shortly afterwards. */</span>
<a name="l00415"></a>00415         xcb_event_set_unmap_notify_handler(&amp;<a class="code" href="a00071.html#a123feed3140395e51010f45a3268464c">evenths</a>, <a class="code" href="a00067.html#af9fc851cafbabe50fa229f4bfb5f0d22" title="Our window decorations were unmapped.">handle_unmap_notify_event</a>, NULL);
<a name="l00416"></a>00416 
<a name="l00417"></a>00417         <span class="comment">/* Destroy notify is handled the same as unmap notify */</span>
<a name="l00418"></a>00418         xcb_event_set_destroy_notify_handler(&amp;<a class="code" href="a00071.html#a123feed3140395e51010f45a3268464c">evenths</a>, <a class="code" href="a00067.html#a8c3b4a8b74d993af20e5078e4a20efed" title="A destroy notify event is sent when the window is not unmapped, but immediately destroyed...">handle_destroy_notify_event</a>, NULL);
<a name="l00419"></a>00419 
<a name="l00420"></a>00420         <span class="comment">/* Configure notify = window’s configuration (geometry, stacking, …). We only need</span>
<a name="l00421"></a>00421 <span class="comment">           it to set up ignore the following enter_notify events */</span>
<a name="l00422"></a>00422         xcb_event_set_configure_notify_handler(&amp;<a class="code" href="a00071.html#a123feed3140395e51010f45a3268464c">evenths</a>, <a class="code" href="a00067.html#aa17e023a1acbf56eb18628e82c8ed55e" title="Configuration notifies are only handled because we need to set up ignore for the...">handle_configure_event</a>, NULL);
<a name="l00423"></a>00423 
<a name="l00424"></a>00424         <span class="comment">/* Configure request = window tried to change size on its own */</span>
<a name="l00425"></a>00425         xcb_event_set_configure_request_handler(&amp;<a class="code" href="a00071.html#a123feed3140395e51010f45a3268464c">evenths</a>, <a class="code" href="a00067.html#abef279a14e8384ccf48371d6a3f6f962" title="Configure requests are received when the application wants to resize windows on their...">handle_configure_request</a>, NULL);
<a name="l00426"></a>00426 
<a name="l00427"></a>00427         <span class="comment">/* Motion notify = user moved his cursor (over the root window and may</span>
<a name="l00428"></a>00428 <span class="comment">         * cross virtual screen boundaries doing that) */</span>
<a name="l00429"></a>00429         xcb_event_set_motion_notify_handler(&amp;<a class="code" href="a00071.html#a123feed3140395e51010f45a3268464c">evenths</a>, <a class="code" href="a00067.html#a23c1d18838f1993a18c1bd891a0fcd3e" title="When the user moves the mouse but does not change the active window (e.g.">handle_motion_notify</a>, NULL);
<a name="l00430"></a>00430 
<a name="l00431"></a>00431         <span class="comment">/* Mapping notify = keyboard mapping changed (Xmodmap), re-grab bindings */</span>
<a name="l00432"></a>00432         xcb_event_set_mapping_notify_handler(&amp;<a class="code" href="a00071.html#a123feed3140395e51010f45a3268464c">evenths</a>, <a class="code" href="a00067.html#a2ca89397c76485894e1de2fcb65ec697" title="Called when the keyboard mapping changes (for example by using Xmodmap), we need...">handle_mapping_notify</a>, NULL);
<a name="l00433"></a>00433 
<a name="l00434"></a>00434         <span class="comment">/* Client message are sent to the root window. The only interesting client message</span>
<a name="l00435"></a>00435 <span class="comment">           for us is _NET_WM_STATE, we honour _NET_WM_STATE_FULLSCREEN */</span>
<a name="l00436"></a>00436         xcb_event_set_client_message_handler(&amp;<a class="code" href="a00071.html#a123feed3140395e51010f45a3268464c">evenths</a>, <a class="code" href="a00067.html#aa3ab831816987a97999392d7b54e4aee" title="Handle client messages (EWMH).">handle_client_message</a>, NULL);
<a name="l00437"></a>00437 
<a name="l00438"></a>00438         <span class="comment">/* Initialize the property handlers */</span>
<a name="l00439"></a>00439         xcb_property_handlers_init(&amp;prophs, &amp;<a class="code" href="a00071.html#a123feed3140395e51010f45a3268464c">evenths</a>);
<a name="l00440"></a>00440 
<a name="l00441"></a>00441         <span class="comment">/* Watch size hints (to obey correct aspect ratio) */</span>
<a name="l00442"></a>00442         xcb_property_set_handler(&amp;prophs, WM_NORMAL_HINTS, UINT_MAX, <a class="code" href="a00067.html#a37b6d4793feaffd6a4a25db3416c0d3f" title="Handles the size hints set by a window, but currently only the part necessary for...">handle_normal_hints</a>, NULL);
<a name="l00443"></a>00443 
<a name="l00444"></a>00444         <span class="comment">/* Get the root window and set the event mask */</span>
<a name="l00445"></a>00445         xcb_screen_t *root_screen = xcb_aux_get_screen(conn, screens);
<a name="l00446"></a>00446         <a class="code" href="a00071.html#a768f07da9e11ab88732a5c550ff49257">root</a> = root_screen-&gt;root;
<a name="l00447"></a>00447         <a class="code" href="a00071.html#a5cc2471a026cd3d2a8800e8ab2c9dcb7">root_depth</a> = root_screen-&gt;root_depth;
<a name="l00448"></a>00448 
<a name="l00449"></a>00449         uint32_t mask = XCB_CW_EVENT_MASK;
<a name="l00450"></a>00450         uint32_t values[] = { XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT |
<a name="l00451"></a>00451                               XCB_EVENT_MASK_STRUCTURE_NOTIFY |         <span class="comment">/* when the user adds a screen (e.g. video</span>
<a name="l00452"></a>00452 <span class="comment">                                                                           projector), the root window gets a</span>
<a name="l00453"></a>00453 <span class="comment">                                                                           ConfigureNotify */</span>
<a name="l00454"></a>00454                               XCB_EVENT_MASK_POINTER_MOTION |
<a name="l00455"></a>00455                               XCB_EVENT_MASK_PROPERTY_CHANGE |
<a name="l00456"></a>00456                               XCB_EVENT_MASK_ENTER_WINDOW };
<a name="l00457"></a>00457         xcb_void_cookie_t cookie;
<a name="l00458"></a>00458         cookie = xcb_change_window_attributes_checked(conn, <a class="code" href="a00071.html#a768f07da9e11ab88732a5c550ff49257">root</a>, mask, values);
<a name="l00459"></a>00459         <a class="code" href="a00077.html#ae8ee4cede01d9a00cbeaffbc5f096f8d" title="Checks a generic cookie for errors and quits with the given message if there was...">check_error</a>(conn, cookie, <span class="stringliteral">&quot;Another window manager seems to be running&quot;</span>);
<a name="l00460"></a>00460 
<a name="l00461"></a>00461         <span class="comment">/* Setup NetWM atoms */</span>
<a name="l00462"></a>00462 <span class="preprocessor">        #define GET_ATOM(name) { \</span>
<a name="l00463"></a>00463 <span class="preprocessor">                xcb_intern_atom_reply_t *reply = xcb_intern_atom_reply(conn, atom_cookies[name], NULL); \</span>
<a name="l00464"></a>00464 <span class="preprocessor">                if (!reply) { \</span>
<a name="l00465"></a>00465 <span class="preprocessor">                        ELOG(&quot;Could not get atom &quot; #name &quot;\n&quot;); \</span>
<a name="l00466"></a>00466 <span class="preprocessor">                        exit(-1); \</span>
<a name="l00467"></a>00467 <span class="preprocessor">                } \</span>
<a name="l00468"></a>00468 <span class="preprocessor">                atoms[name] = reply-&gt;atom; \</span>
<a name="l00469"></a>00469 <span class="preprocessor">                free(reply); \</span>
<a name="l00470"></a>00470 <span class="preprocessor">        }</span>
<a name="l00471"></a>00471 <span class="preprocessor"></span>
<a name="l00472"></a>00472         <a class="code" href="a00071.html#a8b894f92a3b1fcc9d1332bcadd9be933">GET_ATOM</a>(<a class="code" href="a00054.html#a726ca809ffd3d67ab4b8476646f26635a02709e70342f55474db97400e435c636">_NET_SUPPORTED</a>);
<a name="l00473"></a>00473         <a class="code" href="a00071.html#a8b894f92a3b1fcc9d1332bcadd9be933">GET_ATOM</a>(<a class="code" href="a00054.html#a726ca809ffd3d67ab4b8476646f26635accdb5c5ee0d74dfffda6f4324a9abff5">_NET_WM_STATE_FULLSCREEN</a>);
<a name="l00474"></a>00474         <a class="code" href="a00071.html#a8b894f92a3b1fcc9d1332bcadd9be933">GET_ATOM</a>(<a class="code" href="a00054.html#a726ca809ffd3d67ab4b8476646f26635aabc07cc4cd1aea6087dc5763d82576cf">_NET_SUPPORTING_WM_CHECK</a>);
<a name="l00475"></a>00475         <a class="code" href="a00071.html#a8b894f92a3b1fcc9d1332bcadd9be933">GET_ATOM</a>(<a class="code" href="a00054.html#a726ca809ffd3d67ab4b8476646f26635a1dedae1b3288478b95e08984bac0e951">_NET_WM_NAME</a>);
<a name="l00476"></a>00476         <a class="code" href="a00071.html#a8b894f92a3b1fcc9d1332bcadd9be933">GET_ATOM</a>(<a class="code" href="a00054.html#a726ca809ffd3d67ab4b8476646f26635a555588bf6061a168cd7526a49dc4b0fa">_NET_WM_STATE</a>);
<a name="l00477"></a>00477         <a class="code" href="a00071.html#a8b894f92a3b1fcc9d1332bcadd9be933">GET_ATOM</a>(<a class="code" href="a00054.html#a726ca809ffd3d67ab4b8476646f26635ad2b0847e09761bd2ad2b6482c51b07ca">_NET_WM_WINDOW_TYPE</a>);
<a name="l00478"></a>00478         <a class="code" href="a00071.html#a8b894f92a3b1fcc9d1332bcadd9be933">GET_ATOM</a>(<a class="code" href="a00054.html#a726ca809ffd3d67ab4b8476646f26635a92d29c09b7c0af698c72325a0372126f">_NET_WM_DESKTOP</a>);
<a name="l00479"></a>00479         <a class="code" href="a00071.html#a8b894f92a3b1fcc9d1332bcadd9be933">GET_ATOM</a>(<a class="code" href="a00054.html#a726ca809ffd3d67ab4b8476646f26635a2d1c4f653feb0746c9d55bddfa1f8946">_NET_WM_WINDOW_TYPE_DOCK</a>);
<a name="l00480"></a>00480         <a class="code" href="a00071.html#a8b894f92a3b1fcc9d1332bcadd9be933">GET_ATOM</a>(<a class="code" href="a00054.html#a726ca809ffd3d67ab4b8476646f26635afc6c49b0d04427d54227a147e230fa6c">_NET_WM_WINDOW_TYPE_DIALOG</a>);
<a name="l00481"></a>00481         <a class="code" href="a00071.html#a8b894f92a3b1fcc9d1332bcadd9be933">GET_ATOM</a>(<a class="code" href="a00054.html#a726ca809ffd3d67ab4b8476646f26635a2e553ea4ae93c2324801a40f52d7a70a">_NET_WM_WINDOW_TYPE_UTILITY</a>);
<a name="l00482"></a>00482         <a class="code" href="a00071.html#a8b894f92a3b1fcc9d1332bcadd9be933">GET_ATOM</a>(<a class="code" href="a00054.html#a726ca809ffd3d67ab4b8476646f26635adc360a29b4d20ba8cd1c999f6077a843">_NET_WM_WINDOW_TYPE_TOOLBAR</a>);
<a name="l00483"></a>00483         <a class="code" href="a00071.html#a8b894f92a3b1fcc9d1332bcadd9be933">GET_ATOM</a>(<a class="code" href="a00054.html#a726ca809ffd3d67ab4b8476646f26635a49555c0ebb81f76501d672c92857704a">_NET_WM_WINDOW_TYPE_SPLASH</a>);
<a name="l00484"></a>00484         <a class="code" href="a00071.html#a8b894f92a3b1fcc9d1332bcadd9be933">GET_ATOM</a>(<a class="code" href="a00054.html#a726ca809ffd3d67ab4b8476646f26635a5171f3918252a26530d02d6a1716ca45">_NET_WM_STRUT_PARTIAL</a>);
<a name="l00485"></a>00485         <a class="code" href="a00071.html#a8b894f92a3b1fcc9d1332bcadd9be933">GET_ATOM</a>(<a class="code" href="a00054.html#a726ca809ffd3d67ab4b8476646f26635a5d7366da3deea67253099a5c730d4297">WM_PROTOCOLS</a>);
<a name="l00486"></a>00486         <a class="code" href="a00071.html#a8b894f92a3b1fcc9d1332bcadd9be933">GET_ATOM</a>(<a class="code" href="a00054.html#a726ca809ffd3d67ab4b8476646f26635a72e98f8036033fc3b9db52933dd749d0">WM_DELETE_WINDOW</a>);
<a name="l00487"></a>00487         <a class="code" href="a00071.html#a8b894f92a3b1fcc9d1332bcadd9be933">GET_ATOM</a>(<a class="code" href="a00054.html#a726ca809ffd3d67ab4b8476646f26635aef8323bb1a48d3826fa5269e578b4a6a">UTF8_STRING</a>);
<a name="l00488"></a>00488         <a class="code" href="a00071.html#a8b894f92a3b1fcc9d1332bcadd9be933">GET_ATOM</a>(<a class="code" href="a00054.html#a726ca809ffd3d67ab4b8476646f26635a5ce0f911fd3494577cce5417d7b7eea4">WM_STATE</a>);
<a name="l00489"></a>00489         <a class="code" href="a00071.html#a8b894f92a3b1fcc9d1332bcadd9be933">GET_ATOM</a>(<a class="code" href="a00054.html#a726ca809ffd3d67ab4b8476646f26635a13d4dbc6987347bcc7c535570b4e6c2b">WM_CLIENT_LEADER</a>);
<a name="l00490"></a>00490         <a class="code" href="a00071.html#a8b894f92a3b1fcc9d1332bcadd9be933">GET_ATOM</a>(<a class="code" href="a00054.html#a726ca809ffd3d67ab4b8476646f26635a7b3651a6efcb0970efc89dc301c91e5e">_NET_CURRENT_DESKTOP</a>);
<a name="l00491"></a>00491         <a class="code" href="a00071.html#a8b894f92a3b1fcc9d1332bcadd9be933">GET_ATOM</a>(<a class="code" href="a00054.html#a726ca809ffd3d67ab4b8476646f26635ac34e05dfa966932f57aad3f572ed01f2">_NET_ACTIVE_WINDOW</a>);
<a name="l00492"></a>00492         <a class="code" href="a00071.html#a8b894f92a3b1fcc9d1332bcadd9be933">GET_ATOM</a>(<a class="code" href="a00054.html#a726ca809ffd3d67ab4b8476646f26635a5258a6a20735e2ae242453ddaf60d157">_NET_WORKAREA</a>);
<a name="l00493"></a>00493 
<a name="l00494"></a>00494         xcb_property_set_handler(&amp;prophs, <a class="code" href="a00071.html#a327a6e1e08087496e9cb60b9e6f2a499">atoms</a>[<a class="code" href="a00054.html#a726ca809ffd3d67ab4b8476646f26635ad2b0847e09761bd2ad2b6482c51b07ca">_NET_WM_WINDOW_TYPE</a>], UINT_MAX, <a class="code" href="a00067.html#a9f7d547fc847e3dc11747b7d04077c46" title="Handles _NET_WM_WINDOW_TYPE changes.">handle_window_type</a>, NULL);
<a name="l00495"></a>00495         <span class="comment">/* TODO: In order to comply with EWMH, we have to watch _NET_WM_STRUT_PARTIAL */</span>
<a name="l00496"></a>00496 
<a name="l00497"></a>00497         <span class="comment">/* Watch _NET_WM_NAME (= title of the window in UTF-8) property */</span>
<a name="l00498"></a>00498         xcb_property_set_handler(&amp;prophs, <a class="code" href="a00071.html#a327a6e1e08087496e9cb60b9e6f2a499">atoms</a>[<a class="code" href="a00054.html#a726ca809ffd3d67ab4b8476646f26635a1dedae1b3288478b95e08984bac0e951">_NET_WM_NAME</a>], 128, <a class="code" href="a00067.html#a763f921cc825269f3034ac3237f911f2" title="Called when a window changes its title.">handle_windowname_change</a>, NULL);
<a name="l00499"></a>00499 
<a name="l00500"></a>00500         <span class="comment">/* Watch WM_TRANSIENT_FOR property (to which client this popup window belongs) */</span>
<a name="l00501"></a>00501         xcb_property_set_handler(&amp;prophs, WM_TRANSIENT_FOR, UINT_MAX, <a class="code" href="a00067.html#a770ba9d5b30d95d843fe637e2b3910eb" title="Handles the transient for hints set by a window, signalizing that this window is...">handle_transient_for</a>, NULL);
<a name="l00502"></a>00502 
<a name="l00503"></a>00503         <span class="comment">/* Watch WM_NAME (= title of the window in compound text) property for legacy applications */</span>
<a name="l00504"></a>00504         xcb_watch_wm_name(&amp;prophs, 128, <a class="code" href="a00067.html#ac3e59ebb6684722fada02f66582a1787" title="We handle legacy window names (titles) which are in COMPOUND_TEXT encoding.">handle_windowname_change_legacy</a>, NULL);
<a name="l00505"></a>00505 
<a name="l00506"></a>00506         <span class="comment">/* Watch WM_CLASS (= class of the window) */</span>
<a name="l00507"></a>00507         xcb_property_set_handler(&amp;prophs, WM_CLASS, 128, <a class="code" href="a00067.html#a3fdeb5f8c0fbef80784d1d62e4653ed9" title="Store the window classes for jumping to them later.">handle_windowclass_change</a>, NULL);
<a name="l00508"></a>00508 
<a name="l00509"></a>00509         <span class="comment">/* Watch WM_CLIENT_LEADER (= logical parent window for toolbars etc.) */</span>
<a name="l00510"></a>00510         xcb_property_set_handler(&amp;prophs, <a class="code" href="a00071.html#a327a6e1e08087496e9cb60b9e6f2a499">atoms</a>[<a class="code" href="a00054.html#a726ca809ffd3d67ab4b8476646f26635a13d4dbc6987347bcc7c535570b4e6c2b">WM_CLIENT_LEADER</a>], UINT_MAX, <a class="code" href="a00067.html#a3651e94bba743f088fd461a90892ff2f" title="Handles changes of the WM_CLIENT_LEADER atom which specifies if this is a toolwindow...">handle_clientleader_change</a>, NULL);
<a name="l00511"></a>00511 
<a name="l00512"></a>00512         <span class="comment">/* Watch WM_HINTS (contains the urgent property) */</span>
<a name="l00513"></a>00513         xcb_property_set_handler(&amp;prophs, WM_HINTS, UINT_MAX, <a class="code" href="a00067.html#a875fb3362eee6f327b57a6033ed29a51" title="Handles the WM_HINTS property for extracting the urgency state of the window.">handle_hints</a>, NULL);
<a name="l00514"></a>00514 
<a name="l00515"></a>00515         <span class="comment">/* Set up the atoms we support */</span>
<a name="l00516"></a>00516         <a class="code" href="a00077.html#ae8ee4cede01d9a00cbeaffbc5f096f8d" title="Checks a generic cookie for errors and quits with the given message if there was...">check_error</a>(conn, xcb_change_property_checked(conn, XCB_PROP_MODE_REPLACE, <a class="code" href="a00071.html#a768f07da9e11ab88732a5c550ff49257">root</a>, <a class="code" href="a00071.html#a327a6e1e08087496e9cb60b9e6f2a499">atoms</a>[<a class="code" href="a00054.html#a726ca809ffd3d67ab4b8476646f26635a02709e70342f55474db97400e435c636">_NET_SUPPORTED</a>],
<a name="l00517"></a>00517                        ATOM, 32, 7, <a class="code" href="a00071.html#a327a6e1e08087496e9cb60b9e6f2a499">atoms</a>), <span class="stringliteral">&quot;Could not set _NET_SUPPORTED&quot;</span>);
<a name="l00518"></a>00518         <span class="comment">/* Set up the window manager’s name */</span>
<a name="l00519"></a>00519         xcb_change_property(conn, XCB_PROP_MODE_REPLACE, <a class="code" href="a00071.html#a768f07da9e11ab88732a5c550ff49257">root</a>, <a class="code" href="a00071.html#a327a6e1e08087496e9cb60b9e6f2a499">atoms</a>[<a class="code" href="a00054.html#a726ca809ffd3d67ab4b8476646f26635aabc07cc4cd1aea6087dc5763d82576cf">_NET_SUPPORTING_WM_CHECK</a>], WINDOW, 32, 1, &amp;<a class="code" href="a00071.html#a768f07da9e11ab88732a5c550ff49257">root</a>);
<a name="l00520"></a>00520         xcb_change_property(conn, XCB_PROP_MODE_REPLACE, <a class="code" href="a00071.html#a768f07da9e11ab88732a5c550ff49257">root</a>, <a class="code" href="a00071.html#a327a6e1e08087496e9cb60b9e6f2a499">atoms</a>[_NET_WM_NAME], <a class="code" href="a00071.html#a327a6e1e08087496e9cb60b9e6f2a499">atoms</a>[<a class="code" href="a00054.html#a726ca809ffd3d67ab4b8476646f26635aef8323bb1a48d3826fa5269e578b4a6a">UTF8_STRING</a>], 8, strlen(<span class="stringliteral">&quot;i3&quot;</span>), <span class="stringliteral">&quot;i3&quot;</span>);
<a name="l00521"></a>00521 
<a name="l00522"></a>00522         <a class="code" href="a00071.html#a5cc0138ae2cf3bbb63a7cae907620797">keysyms</a> = xcb_key_symbols_alloc(conn);
<a name="l00523"></a>00523 
<a name="l00524"></a>00524         <a class="code" href="a00079.html#aeae86e9fc76e08fd43f142de4d11bba0" title="Finds out which modifier mask is the one for numlock, as the user may change this...">xcb_get_numlock_mask</a>(conn);
<a name="l00525"></a>00525 
<a name="l00526"></a>00526         <a class="code" href="a00062.html#a0ee8ffa5c11aeb96126b36171da84adc" title="Translates keysymbols to keycodes for all bindings which use keysyms.">translate_keysyms</a>();
<a name="l00527"></a>00527         <a class="code" href="a00062.html#a1741cf749eb2243cca453355d3f6879b" title="Grab the bound keys (tell X to send us keypress events for those keycodes).">grab_all_keys</a>(conn, <span class="keyword">false</span>);
<a name="l00528"></a>00528 
<a name="l00529"></a>00529         <span class="keywordtype">int</span> randr_base;
<a name="l00530"></a>00530         <span class="keywordflow">if</span> (force_xinerama) {
<a name="l00531"></a>00531                 <a class="code" href="a00080.html#a93044db4172ab2447725a2bee3065931" title="We have just established a connection to the X server and need the initial Xinerama...">initialize_xinerama</a>(conn);
<a name="l00532"></a>00532         } <span class="keywordflow">else</span> {
<a name="l00533"></a>00533                 <a class="code" href="a00044.html#a287e239c800086178591f5e53f5bb82c">DLOG</a>(<span class="stringliteral">&quot;Checking for XRandR...\n&quot;</span>);
<a name="l00534"></a>00534                 <a class="code" href="a00073.html#a6a7a017cf0668c2b9aba5011bdd7e9f3" title="We have just established a connection to the X server and need the initial XRandR...">initialize_randr</a>(conn, &amp;randr_base);
<a name="l00535"></a>00535 
<a name="l00536"></a>00536                 xcb_event_set_handler(&amp;<a class="code" href="a00071.html#a123feed3140395e51010f45a3268464c">evenths</a>,
<a name="l00537"></a>00537                                       randr_base + XCB_RANDR_SCREEN_CHANGE_NOTIFY,
<a name="l00538"></a>00538                                       <a class="code" href="a00067.html#a38db143e8cde0e72a7fe1aa1a9412c0e" title="Gets triggered upon a RandR screen change event, that is when the user changes the...">handle_screen_change</a>,
<a name="l00539"></a>00539                                       NULL);
<a name="l00540"></a>00540         }
<a name="l00541"></a>00541 
<a name="l00542"></a>00542         xcb_flush(conn);
<a name="l00543"></a>00543 
<a name="l00544"></a>00544         <span class="comment">/* Get pointer position to see on which screen we’re starting */</span>
<a name="l00545"></a>00545         xcb_query_pointer_reply_t *reply;
<a name="l00546"></a>00546         <span class="keywordflow">if</span> ((reply = xcb_query_pointer_reply(conn, xcb_query_pointer(conn, <a class="code" href="a00071.html#a768f07da9e11ab88732a5c550ff49257">root</a>), NULL)) == NULL) {
<a name="l00547"></a>00547                 <a class="code" href="a00044.html#a6828c68e0feb4b7fdfe0fc3ba9f3038b">ELOG</a>(<span class="stringliteral">&quot;Could not get pointer position\n&quot;</span>);
<a name="l00548"></a>00548                 <span class="keywordflow">return</span> 1;
<a name="l00549"></a>00549         }
<a name="l00550"></a>00550 
<a name="l00551"></a>00551         <a class="code" href="a00026.html" title="An Output is a physical output on your graphics driver.">Output</a> *screen = <a class="code" href="a00073.html#abb7e75366265212195afd09ab85235f6" title="Returns the active (!) output which contains the coordinates x, y or NULL if there...">get_output_containing</a>(reply-&gt;root_x, reply-&gt;root_y);
<a name="l00552"></a>00552         <span class="keywordflow">if</span> (screen == NULL) {
<a name="l00553"></a>00553                 <a class="code" href="a00044.html#a6828c68e0feb4b7fdfe0fc3ba9f3038b">ELOG</a>(<span class="stringliteral">&quot;ERROR: No screen at %d x %d, starting on the first screen\n&quot;</span>,
<a name="l00554"></a>00554                     reply-&gt;root_x, reply-&gt;root_y);
<a name="l00555"></a>00555                 screen = <a class="code" href="a00073.html#a514adc4dcfc06b1e9329e41633c65fb0" title="Returns the first output which is active.">get_first_output</a>();
<a name="l00556"></a>00556         }
<a name="l00557"></a>00557 
<a name="l00558"></a>00558         <a class="code" href="a00044.html#a287e239c800086178591f5e53f5bb82c">DLOG</a>(<span class="stringliteral">&quot;Starting on %p\n&quot;</span>, screen-&gt;<a class="code" href="a00026.html#a9bcf702b65d8f47f98eafbefff529ffe" title="Current workspace selected on this virtual screen.">current_workspace</a>);
<a name="l00559"></a>00559         <a class="code" href="a00076.html#a6dc99dff7063221c1096561951c0386b">c_ws</a> = screen-&gt;<a class="code" href="a00026.html#a9bcf702b65d8f47f98eafbefff529ffe" title="Current workspace selected on this virtual screen.">current_workspace</a>;
<a name="l00560"></a>00560 
<a name="l00561"></a>00561         <a class="code" href="a00072.html#a525375308e06d233e560f4e739e02ca6" title="Go through all existing windows (if the window manager is restarted) and manage them...">manage_existing_windows</a>(conn, &amp;prophs, <a class="code" href="a00071.html#a768f07da9e11ab88732a5c550ff49257">root</a>);
<a name="l00562"></a>00562 
<a name="l00563"></a>00563         <span class="comment">/* Create the UNIX domain socket for IPC */</span>
<a name="l00564"></a>00564         <span class="keywordflow">if</span> (<a class="code" href="a00062.html#a4a8dd3a2de125b72d4fe6251a0a271b5">config</a>.<a class="code" href="a00010.html#a79aa7dde4fb7016d2e71a6433ec467b1">ipc_socket_path</a> != NULL) {
<a name="l00565"></a>00565                 <span class="keywordtype">int</span> ipc_socket = <a class="code" href="a00068.html#a173c2426068f80edfacc45e1fca642d4" title="Creates the UNIX domain socket at the given path, sets it to non-blocking mode, bind()s...">ipc_create_socket</a>(<a class="code" href="a00062.html#a4a8dd3a2de125b72d4fe6251a0a271b5">config</a>.<a class="code" href="a00010.html#a79aa7dde4fb7016d2e71a6433ec467b1">ipc_socket_path</a>);
<a name="l00566"></a>00566                 <span class="keywordflow">if</span> (ipc_socket == -1) {
<a name="l00567"></a>00567                         <a class="code" href="a00044.html#a6828c68e0feb4b7fdfe0fc3ba9f3038b">ELOG</a>(<span class="stringliteral">&quot;Could not create the IPC socket, IPC disabled\n&quot;</span>);
<a name="l00568"></a>00568                 } <span class="keywordflow">else</span> {
<a name="l00569"></a>00569                         <span class="keyword">struct </span>ev_io *ipc_io = <a class="code" href="a00077.html#ad475e1b898d9da9b2a8b92e3da51b3dd" title="Safe-wrapper around calloc which exits if malloc returns NULL (meaning that there...">scalloc</a>(<span class="keyword">sizeof</span>(<span class="keyword">struct</span> ev_io));
<a name="l00570"></a>00570                         ev_io_init(ipc_io, <a class="code" href="a00068.html#ab60981ffa93c190e40d52e05f6c8a4d8" title="Handler for activity on the listening socket, meaning that a new client has just...">ipc_new_client</a>, ipc_socket, EV_READ);
<a name="l00571"></a>00571                         ev_io_start(loop, ipc_io);
<a name="l00572"></a>00572                 }
<a name="l00573"></a>00573         }
<a name="l00574"></a>00574 
<a name="l00575"></a>00575         <span class="comment">/* Handle the events which arrived until now */</span>
<a name="l00576"></a>00576         <a class="code" href="a00071.html#ae803eb28e01465a23d3106d041d20a35">xcb_check_cb</a>(NULL, NULL, 0);
<a name="l00577"></a>00577 
<a name="l00578"></a>00578         <a class="code" href="a00075.html#ae057b3065391c2db8120a38fe9d805b4" title="Setup signal handlers to safely handle SIGSEGV and SIGFPE.">setup_signal_handler</a>();
<a name="l00579"></a>00579 
<a name="l00580"></a>00580         <span class="comment">/* Ignore SIGPIPE to survive errors when an IPC client disconnects</span>
<a name="l00581"></a>00581 <span class="comment">         * while we are sending him a message */</span>
<a name="l00582"></a>00582         signal(SIGPIPE, SIG_IGN);
<a name="l00583"></a>00583 
<a name="l00584"></a>00584         <span class="comment">/* Ungrab the server to receive events and enter libev’s eventloop */</span>
<a name="l00585"></a>00585         xcb_ungrab_server(conn);
<a name="l00586"></a>00586 
<a name="l00587"></a>00587         <span class="comment">/* Autostarting exec-lines */</span>
<a name="l00588"></a>00588         <span class="keyword">struct </span><a class="code" href="a00002.html" title="Holds a command specified by an exec-line in the config (see src/config.c).">Autostart</a> *exec;
<a name="l00589"></a>00589         <span class="keywordflow">if</span> (autostart) {
<a name="l00590"></a>00590                 <a class="code" href="a00047.html#a16e5fc168e7f3494d4b1df54447d871e">TAILQ_FOREACH</a>(exec, &amp;<a class="code" href="a00071.html#adc8cf28482f0bbe29f8bdcba0e32d16f">autostarts</a>, <a class="code" href="a00071.html#adc8cf28482f0bbe29f8bdcba0e32d16f">autostarts</a>) {
<a name="l00591"></a>00591                         <a class="code" href="a00044.html#a388edf12256bf73c3a8ee9734c3bd841" title="#__VA_ARGS__ means: leave out __VA_ARGS__ completely if it is empty, that is, delete...">LOG</a>(<span class="stringliteral">&quot;auto-starting %s\n&quot;</span>, exec-&gt;<a class="code" href="a00002.html#a6286090e69f758678cafeb975607ff97" title="Command, like in command mode.">command</a>);
<a name="l00592"></a>00592                         <a class="code" href="a00077.html#a4a1b0dbf1f2e37a0ad5a0f6cc786225c" title="Starts the given application by passing it through a shell.">start_application</a>(exec-&gt;<a class="code" href="a00002.html#a6286090e69f758678cafeb975607ff97" title="Command, like in command mode.">command</a>);
<a name="l00593"></a>00593                 }
<a name="l00594"></a>00594         }
<a name="l00595"></a>00595 
<a name="l00596"></a>00596         ev_loop(loop, 0);
<a name="l00597"></a>00597 
<a name="l00598"></a>00598         <span class="comment">/* not reached */</span>
<a name="l00599"></a>00599         <span class="keywordflow">return</span> 0;
<a name="l00600"></a>00600 }
</pre></div></div>
<hr class="footer"/><address style="text-align: right;"><small>Generated by&nbsp;
<a href="http://www.doxygen.org/index.html">
<img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.6.2-20100208 </small></address>
</body>
</html>