Sophie

Sophie

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

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

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<HEAD>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<TITLE>LIRC - Linux Infrared Remote Control</TITLE>
<LINK REL="stylesheet" TYPE="text/css" HREF="lirc.css">
<LINK REL="shortcut icon" HREF="../images/favicon.ico">
<META NAME="description" CONTENT="LIRC - Linux Infrared Remote Control">
<META NAME="keywords" CONTENT="linux remote control, multimedia">
<META charset="UTF-8">
</HEAD>
<body>
<TABLE CLASS="menu"><TR>
<TD CLASS="menu"><IMG class="menuimg" SRC="../images/diode.gif" ALT="LIRC icon" ALIGN="LEFT"></TD>
<TD><IMG class="menuimg" SRC="../images/lirc.gif" ALT="LIRC logo" ALIGN="RIGHT"></TD>
</TR></TABLE>
<a name="lirc_client"></a><hr>
<center><h1>The lirc_client API</h1></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>

    /****************************************************************************
     ** irexec.c ****************************************************************
     ****************************************************************************
     *
     * irexec  - execute programs according to the pressed remote control buttons
     *
     * Copyright (C) 1998 Trent Piepho &lt;xyzzy@u.washington.edu&gt;
     * Copyright (C) 1998 Christoph Bartelmus &lt;lirc@bartelmus.de&gt;
     *
     */

    #ifdef HAVE_CONFIG_H
    # include &lt;config.h&gt;
    #endif

    #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"

    char *progname;

    int main(int argc, char *argv[])
    {
            struct lirc_config *config;
            char *code;
            char *c;
            int ret;

            progname=argv[0];
            if(argc&gt;2)
            {
                    fprintf(stderr,"Usage: %s &lt;config file&gt;\n",progname);
                    exit(EXIT_FAILURE);
            }
            if( lirc_init("irexec",1) == -1)
                    exit EXIT_FAILURE;

            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);
            }

            lirc_deinit();
            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>lirc_client.h</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>lirc_init()</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>lirc_readconfig()</em> function:
</p>
<pre>
    int lirc_readconfig(char *file,struct lirc_config **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>

  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>lirc_code2char()</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>lirc_init()</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>lirc_nextcode()</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 lirc_nextcode(char **code);
</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>

  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>lirc_init()</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>

  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>lirc_nextcode()</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 lirc_code2char(struct lirc_config *config,char *code,char **string);
</pre>
<p>
  <em>config</em> is a pointer to the config file data structure
  that you can get with <em>lirc_readconfig()</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 lirc_freeconfig(struct lirc_config *config);
</pre>
<p>
  This functions frees the data structures associated with
  <em>config</em>.
</p>
<pre>
    int lirc_deinit();
</pre>
<p>
  <em>lirc_deinit()</em> closes the connection to lircd and does
  some internal clean-up stuff.
</p>

<h3>Sending data</h3>
Sending (blasting) is done according to following:

<pre>

#include "lirc_client.h"

int main(int argc, char** argv)
{
    int fd;

    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>
<p></p>
<ul>
   <li>
     Feeding NULL to lirc_get_local_socket() 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>
lirc_send_one() and lirc_simulate() are blocking. If you need to do
non-blocking IO and/or access other functionality available you need to
use lirc_command_init() and lirc_command_run(). 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
<i>lirc-setup</i> and the <i>data2table</i> and <i>data2html</i> 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>

    import lirc

    # 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

    # 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>

    import lirc

    #... 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>
<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:
<pre>

    import asyncio
    from lirc import AsyncConnection, LircdConnection

    async def get_lines(raw_conn):
        async with AsyncConnection(raw_conn, loop) as conn:
            async for keypress in conn:
                ... do something with keypress

    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>
Besides the API docs there is also a directory <i>doc/python-bindings</i>
in the distribution. This contains a bunch of small snippets which
demonstrates the python API.</p>


<h3>Autoconf support</h3>

<p>
  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>:
</p>
<pre>
    dnl Check for LIRC client support
    PKG_CHECK_MODULES([LIRC], [lirc],,)
</pre>
<p>
  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).  </p>
</code></code></p>
<p class="footer">
        [<A HREF="http://www.lirc.org/">LIRC homepage</A>]
      </p>
</body>
</html>