Sophie

Sophie

distrib > Mageia > 7 > armv7hl > by-pkgid > eb6f01499a5d4428f90019094419e1c5 > files > 301

liblirc-devel-0.10.1-7.mga7.armv7hl.rpm

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://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"/>
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
<meta name="generator" content="Doxygen 1.8.15"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>LIRC libraries: Client API manual excerpt.</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<link href="navtree.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="resize.js"></script>
<script type="text/javascript" src="navtreedata.js"></script>
<script type="text/javascript" src="navtree.js"></script>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&amp;dn=gpl-2.0.txt GPL-v2 */
  $(document).ready(initResizable);
/* @license-end */</script>
<link href="search/search.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="search/searchdata.js"></script>
<script type="text/javascript" src="search/search.js"></script>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
 <tbody>
 <tr style="height: 56px;">
  <td id="projectlogo"><img alt="Logo" src="diode-2.gif"/></td>
  <td id="projectalign" style="padding-left: 0.5em;">
   <div id="projectname">LIRC libraries
   </div>
   <div id="projectbrief">LinuxInfraredRemoteControl</div>
  </td>
 </tr>
 </tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.8.15 -->
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&amp;dn=gpl-2.0.txt GPL-v2 */
var searchBox = new SearchBox("searchBox", "search",false,'Search');
/* @license-end */
</script>
<script type="text/javascript" src="menudata.js"></script>
<script type="text/javascript" src="menu.js"></script>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&amp;dn=gpl-2.0.txt GPL-v2 */
$(function() {
  initMenu('',true,false,'search.php','Search');
  $(document).ready(function() { init_search(); });
});
/* @license-end */</script>
<div id="main-nav"></div>
</div><!-- top -->
<div id="side-nav" class="ui-resizable side-nav-resizable">
  <div id="nav-tree">
    <div id="nav-tree-contents">
      <div id="nav-sync" class="sync"></div>
    </div>
  </div>
  <div id="splitbar" style="-moz-user-select:none;" 
       class="ui-resizable-handle">
  </div>
</div>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&amp;dn=gpl-2.0.txt GPL-v2 */
$(document).ready(function(){initNavTree('group__client__manual.html','');});
/* @license-end */
</script>
<div id="doc-content">
<!-- window showing the filter options -->
<div id="MSearchSelectWindow"
     onmouseover="return searchBox.OnSearchSelectShow()"
     onmouseout="return searchBox.OnSearchSelectHide()"
     onkeydown="return searchBox.OnSearchSelectKey(event)">
</div>

<!-- iframe showing the search results (closed by default) -->
<div id="MSearchResultsWindow">
<iframe src="javascript:void(0)" frameborder="0" 
        name="MSearchResults" id="MSearchResults">
</iframe>
</div>

<div class="header">
  <div class="headertitle">
<div class="title">Client API manual excerpt.</div>  </div>
</div><!--header-->
<div class="contents">

<p>Client API manual excerpt <a class="anchor" id="lirc_client"></a>  
<a href="#details">More...</a></p>
<p>Client API manual excerpt <a class="anchor" id="lirc_client"></a> </p>
<hr/>
 <center><h1>The lirc_client API</h1>
</center><center></center> <hr/>
 <p>Since 0.6.0, the client API have supported receiving data. Since 0.9.2+, the API also supports sending of data. Since 0.10.0+ there is also a Python interface supporting both send and receive. </p>
<p>This text is also available in the <a href="../api-docs/html/index.html">API documentation</a> (under Modules). This variant is more detailed, and linked by Doxygen to the sources. </p>
<h3>Receiving data</h3>
<p>If you only want to make your application to receive commands and if you don't want to mess with all the protocol stuff you can use the <em>lirc_client</em> library that comes with LIRC since version 0.6.0. With the help of this library a program can be as simple as this to receive data. </p>
<pre></pre><pre>    /****************************************************************************
        irexec.c ****************************************************************</pre><pre>       irexec  - execute programs according to the pressed remote control buttons</pre><pre>       Copyright (C) 1998 Trent Piepho &lt;<a href="#" onclick="location.href='mai'+'lto:'+'xyz'+'zy'+'@u.'+'wa'+'shi'+'ng'+'ton'+'.e'+'du'; return false;">xyzzy<span style="display: none;">.nosp@m.</span>@u.w<span style="display: none;">.nosp@m.</span>ashin<span style="display: none;">.nosp@m.</span>gton<span style="display: none;">.nosp@m.</span>.edu</a>&gt;
       Copyright (C) 1998 Christoph Bartelmus &lt;<a href="#" onclick="location.href='mai'+'lto:'+'lir'+'c@'+'bar'+'te'+'lmu'+'s.'+'de'; return false;">lirc@<span style="display: none;">.nosp@m.</span>bart<span style="display: none;">.nosp@m.</span>elmus<span style="display: none;">.nosp@m.</span>.de</a>&gt;</pre><pre>     */</pre><pre>    #ifdef HAVE_CONFIG_H
    # include &lt;<a class="el" href="config_8h_source.html">config.h</a>&gt;
    #endif</pre><pre>    #include &lt;errno.h&gt;
    #include &lt;unistd.h&gt;
    #include &lt;stdarg.h&gt;
    #include &lt;stdio.h&gt;
    #include &lt;stdlib.h&gt;
    #include &lt;string.h&gt;
    #include "lirc_client.h"</pre><pre>    char *progname;</pre><pre>    int main(int argc, char *argv[])
    {
            struct <a class="el" href="structlirc__config.html">lirc_config</a> *config;
            char *code;
            char *c;
            int ret;</pre><pre>            progname=argv[0];
            if(argc&gt;2)
            {
                    fprintf(stderr,"Usage: %s &amp;lt;config file&amp;gt;\n",progname);
                    exit(EXIT_FAILURE);
            }
            if( lirc_init("irexec",1) == -1)
                    exit EXIT_FAILURE;</pre><pre>            if( lirc_readconfig(argc == 2 ? argv[1] : NULL,&amp;config,NULL) == 0) {
                    while( lirc_nextcode(&amp;code) == 0)
                    {
                            if (code == NULL) continue;
                            while(( ret = lirc_code2char( config,code,&amp;c)) == 0 &amp;&amp;
                                  c != NULL)
                            {
                                   printf("Execing command \"%s"\n",c);
                                   system(c);
                            }
                            free(code);
                            if(ret==-1) break;
                    }
                    lirc_freeconfig(config);
            }</pre><pre>            <a class="el" href="group__lirc__client.html#ga50999022b09857ba43aa2f3f29c72b9e" title="Release resources allocated by lirc_init(), basically disconnect from socket.">lirc_deinit()</a>;
            exit(EXIT_SUCCESS);
    }
</pre><p>Before anything else you have to include the header file for the lirc_client library. This is done with </p>
<pre>
    #include &lt;lirc/lirc_client.h&gt;
</pre> <p>Note that our example differs in this point because it was taken directly from the lirc-0.6.0 source that comes with its own <em><a class="el" href="lirc__client_8h.html" title="3-rd party application interface.">lirc_client.h</a></em> but we have to use the one that is already installed on the system. </p>
<p>The next step is to initialize the library code with <em><a class="el" href="group__lirc__client.html#gaf92c865f0895259aa40e2aed51c71001" title="Initial setup: connect to lircd socket.">lirc_init()</a></em>. This function connects to lircd and does some internal init stuff. </p>
<pre>
    int lirc_init(char *prog,int verbose);
</pre> <p>The first argument to this function is the string users will have to provide as <em>prog</em> token in their .lircrc config files. If the second argument is non-zero error messages will be printed to <em>stderr</em>. Otherwise no error messages will ever be displayed. This function returns the file descriptor of the socket that is connected to lircd or -1 if an error occurred. </p>
<p>By default the client connects to the hard-coded default path, usually /var/run/lirc/lircd. The environment variable LIRC_SOCKET_PATH can be used to connect to another socket. </p>
<p>The example continues by reading a config file. This is done by the <em><a class="el" href="group__lirc__client.html#ga62e50c43a39bd8858d42bc11adf40972" title="Parse a lircrc configuration file.">lirc_readconfig()</a></em> function: </p>
<pre>
    int lirc_readconfig(char *file,struct <a class="el" href="structlirc__config.html">lirc_config</a> **config,
                        int (check)(char *s));
</pre> <p>If you want to load the default config file you should pass NULL as first argument. If you want to load some other config file the <em>file</em> argument should contain the complete path to the file. Your program should give the user the possibility to use an other than the default config file. You should also be able to load multiple config files by calling this function several times.<br />
</p>
<p>The <em>config</em> argument is used to pass the pointer to the config file data structures back to your application. You will need it for calls to the <em><a class="el" href="group__lirc__client.html#ga8cb15780179dec56adc42559ee964a68" title="Translate a code string to an application string using .lircrc.">lirc_code2char()</a></em> function. The last argument is a call-back function that can be used to do syntax checks with the config strings. The library code will call the call-back function for all config strings where the <em>prog</em> token in the config file matches the prog string you provided with the <em><a class="el" href="group__lirc__client.html#gaf92c865f0895259aa40e2aed51c71001" title="Initial setup: connect to lircd socket.">lirc_init()</a></em> function. If there is an error in the config string the call-back function should return -1, otherwise 0. If you don't need to do any syntax checks you can pass NULL here. The function returns -1 if an error occurred, 0 otherwise. </p>
<p>The <em><a class="el" href="group__lirc__client.html#gaf352dc9bb17d32c0f867ce5ca8a2f2d3" title="Get next available code from the lircd daemon.">lirc_nextcode()</a></em> function blocks until there is something available on the lircd socket. This way it can be used in the main loop of your program like in our example. </p>
<pre>
    int <a class="el" href="group__lirc__client.html#gaf352dc9bb17d32c0f867ce5ca8a2f2d3" title="Get next available code from the lircd daemon.">lirc_nextcode(char **code)</a>;
</pre> <p>If an error occurs (usually this means that the socket has been closed by the daemon) this function returns -1. Otherwise it returns 0 and <em>code</em> points to the next string available in the data stream. This string has to be freed by your application using the <em>free(3)</em> function. If no complete string is available <em>code</em> will be NULL.<br />
</p>
<p>If you use some GUI-toolkit for your program then you probably won't be able to use this function in your program's main loop because this is already handled by the GUI-toolkit. In this situation you should use the call-back abilities of the toolkit that will notify you whenever there is some input available from a file descriptor (you get the file descriptor from the <em><a class="el" href="group__lirc__client.html#gaf92c865f0895259aa40e2aed51c71001" title="Initial setup: connect to lircd socket.">lirc_init()</a></em> function). E.g. you can use the <em>gdk_input_add()</em>/<em>gdk_input_remove</em>() functions with gtk or the <em>QSocketNotifier</em> class with Qt. If you don't have such functionality in your toolkit or can't use it for some reason you can still use SIGIO signals for this purpose. Check the documentation for your GUI-toolkit and signal(2) for further information.<br />
</p>
<p>Please note that using call-backs you still have to use some kind of while loop to read strings from the socket because several strings may be available in the data stream and you will only get a notification for the first one. This poses a problem for us because <em><a class="el" href="group__lirc__client.html#gaf352dc9bb17d32c0f867ce5ca8a2f2d3" title="Get next available code from the lircd daemon.">lirc_nextcode()</a></em> blocks until there is something available from the socket which is not what we need here. You can solve this problem by setting the <b>O_NONBLOCK</b> flag for the socket using the <em>fcntl(2)</em> function. Have a look at the current xirw code that is available from the LIRC homepage for an implementation example. </p>
<p>To get the config string that the user has provided in the config file in response to a button press you use the following function: </p>
<pre>
    int <a class="el" href="group__lirc__client.html#ga8cb15780179dec56adc42559ee964a68" title="Translate a code string to an application string using .lircrc.">lirc_code2char(struct lirc_config *config,char *code,char **string)</a>;
</pre> <p><em>config</em> is a pointer to the config file data structure that you can get with <em><a class="el" href="group__lirc__client.html#ga62e50c43a39bd8858d42bc11adf40972" title="Parse a lircrc configuration file.">lirc_readconfig()</a></em> and <em>code</em> is the code transmitted to your application on the lircd socket. If an action should be taken <em>string</em> will point to the config string the user has provided in the config file. The user might want to take several actions on a button press so you have to execute this function until <em>string</em> is NULL, which means that no more actions shall be taken, or an error occurs. The function returns -1 if an error occurred, 0 otherwise. </p>
<p>In our example there are only two clean-up functions to be explained. </p>
<pre>
    void <a class="el" href="group__lirc__client.html#ga771f0592a8d378bc2ea314fdf4efa233" title="Deallocate an object retrieved using lirc_readconfig().">lirc_freeconfig(struct lirc_config *config)</a>;
</pre> <p>This functions frees the data structures associated with <em>config</em>. </p>
<pre>
    int <a class="el" href="group__lirc__client.html#ga50999022b09857ba43aa2f3f29c72b9e" title="Release resources allocated by lirc_init(), basically disconnect from socket.">lirc_deinit()</a>;
</pre> <p><em><a class="el" href="group__lirc__client.html#ga50999022b09857ba43aa2f3f29c72b9e" title="Release resources allocated by lirc_init(), basically disconnect from socket.">lirc_deinit()</a></em> closes the connection to lircd and does some internal clean-up stuff. </p>
<h3>Sending data</h3>
<p>Sending (blasting) is done according to following:</p>
<pre></pre><pre>#include "lirc_client.h"</pre><pre>int main(int argc, char** argv)
{
    int fd;</pre><pre>    fd = lirc_get_local_socket(NULL, 0);
    if (fd &lt; 0) {
        // Process error
    }
    if (lirc_send_one(fd, "name of remote", "Key symbol") == -1) {
        // Process errors
    };
}
</pre><p>Notes: </p>
<ul>
<li>
Feeding NULL to <a class="el" href="group__lirc__client.html#ga13cf4c784df60143d2b171645f4e84c1" title="Return an opened and connected file descriptor to local lirc socket.">lirc_get_local_socket()</a> will make it use the default lircd socket. Doing so, it respects the LIRC_SOCKET_PATH environment variable. </li>
<li>
<em>Name of remote</em> is the mandatory name attribute in the lircd.conf config file. </li>
<li>
<em>Key symbol</em> is the name of a key definition in the lircd.conf file. </li>
</ul>
<p><a class="el" href="group__lirc__client.html#ga0e86e3a29c14dc8047651e0bb9c49b31" title="Send keysym using given remote.">lirc_send_one()</a> and <a class="el" href="group__lirc__client.html#gad5d41d33e0c1fc3002cdf8c0d9aa43d5" title="Send a simulated lirc event.This call might block for some time since it involves communication with ...">lirc_simulate()</a> are blocking. If you need to do non-blocking IO and/or access other functionality available you need to use <a class="el" href="group__lirc__client.html#ga3787c58d32391a5b7c40337fdbee95fc" title="Initiate a lirc_cmd_ctx to run a command.">lirc_command_init()</a> and <a class="el" href="group__lirc__client.html#ga888d275e1b0cf4988e44fb15f24d2a99" title="Run a command in non-blocking mode.">lirc_command_run()</a>. Example code is in irsend.cpp. </p>
<h3>Using the Python API </h3>
<p>The Python API's main documentation is in the API docs, look for <em> Python Bindings</em> under Modules. This text is just an introduction.</p>
<p>Besides the client API described here there are also <code>lirc.config</code> and <code>lirc.database</code> interfaces. These are not documented as of now. The config is some read-only paths as defined by configure. The database is the python view of the configs/ directory; example usage in <em>lirc-setup</em> and the <em>data2table</em> and <em>data2html</em> scripts in doc/ </p>
<p>In the client API the receive parts supports both raw keypress events as displayed by irw(1) or application-specific strings as presented by ircat(1). Receiving raw events is done like: </p><pre></pre><pre>    import lirc</pre><pre>    # Setup path, the lircd output socket path
    with lirc.RawConnection(path) as conn:
        press = conn.readline()
        # ... do something with press
</pre> <p>The path argument can be omitted on default installations, lirc_client will make an educated guess based on environment, lirc_options.conf and hard-coded defaults.</p>
<p>Receiving application-specific strings goes like: </p><pre>
    import lirc</pre><pre>    # setup lircrc_path and program.
    with lirc.LircdConnection(
            program, lircrc_path, socket_path) as conn:
        while True:
             string = conn.readline()
             # ... do something with string
</pre> <p>Here, user needs to define program (see ircat(1)), the path to the lircrc config file and the socket path. Like in previous example, lirc_client often can guess the socket_path and lircrc_path arguments in standard installations..</p>
<p>Sending is slightly more complex. A simple example is to retrieve the lircd version over the socket interface which is done like this: </p><pre></pre><pre>    import lirc</pre><pre>    #... again, the path to the lircd socket might be needed
    with lirc.CommandConnection(socket_path=...) as conn:
        reply = lirc.VersionCommand(conn).run()
    if reply.success:
        print(parser.data[0])
    else:
        print("Error: " + parser.data[0])</pre><pre></pre> <p>The object returned by command.run() is a <em>Reply</em> with all info on the command outcome.</p>
<p>Asynchronous IO is relatively straight-forward. Using the <code>AsyncConnection<code> receiving data from a <code> RawConnection</code> or a <code>LircdConnection</code> goes like: </p><pre></pre><p></code></code></p>
<p><code><code></p><pre>    import asyncio
    from lirc import AsyncConnection, LircdConnection</pre><p></code></code></p>
<p><code><code></p><pre>    async def get_lines(raw_conn):
        async with AsyncConnection(raw_conn, loop) as conn:
            async for keypress in conn:
                ... do something with keypress</pre><p></code></code></p>
<p><code><code></p><pre>    loop = asyncio.get_event_loop()
    with LircdConnection('foo',
                         socket_path=...,
                         lircrc_path=....) as conn:
        loop.run_until_complete(get_lines(conn))
    loop.close()</pre><p></code></code></p>
<p><code><code></p><pre></pre><p> </code></code></p>
<p><code><code> Besides the API docs there is also a directory <em>doc/python-bindings</em> in the distribution. This contains a bunch of small snippets which demonstrates the python API.</code></code></p>
<p><code><code></code></code></p>
<p><code><code></p><h3>Autoconf support</h3>
<p></code></code></p>
<p><code><code></code></code></p>
<p><code><code></code></code></p>
<p><code><code> LIRC has full support for autocont an pkg-config. To check for the lirc_client library all what is required is to insert the following into <em>configure.ac</em>: </code></code></p>
<p><code><code> </p><pre>
    dnl Check for LIRC client support
    PKG_CHECK_MODULES([LIRC], [lirc],,)
</pre><p> </code></code></p>
<p><code><code> This will setup the variables LIRC_FLAGS and LIRC_LIBS which can be used to augment AM_CPPFLAGS and AM_LIBS. See pkg-config(3). </code></code></p>
<p><code><code> </code></code></p>
</div><!-- contents -->
</div><!-- doc-content -->
<!-- start footer part -->
<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
  <ul>
    <li class="footer">Generated by
    <a href="http://www.doxygen.org/index.html">
    <img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.8.15 </li>
  </ul>
</div>
</body>
</html>