\hypertarget{group__driver__manual}{}\section{Driver A\+P\+I manual excerpt}
\label{group__driver__manual}\index{Driver A\+P\+I manual excerpt@{Driver A\+P\+I manual excerpt}}


Driver A\+P\+I manual excerpt.  


Driver A\+P\+I manual excerpt. 



 \subsection*{Documentation of the L\+I\+R\+C driver A\+P\+I version 2.}





This document describes the A\+P\+I used by the L\+I\+R\+C userspace drivers in version 2.

It is targeted at active C programmers, and not written with the intention to be understandable by non-\/programmers. 

The guide aims at being fully compatible with the upcoming release L\+I\+R\+C 0.\+9.\+2. (C\+L\+A\+R\+I\+F\+Y)



 ~\newline
 \subsection*{Introduction}

There are three kinds of drivers in L\+I\+R\+C\+: 
\begin{DoxyEnumerate}
\item Kernel drivers, also called kernel modules.  
\item User space, statically linked drivers. 
\item User space, dynamically linked drivers. 
\end{DoxyEnumerate}

Kernel drivers will not be covered in the present article. User space drivers are nothing else but normal compiled C functions, running as the invoking user (which may or may not be root). Therefore, the decomposition between \char`\"{}program\char`\"{} and driver is a priori not always necessary, but instead serves modularization and structuring. 

In the beginning, due to its focus on very simple hardware, L\+I\+R\+C was very centered around kernal modules like directly connected L\+E\+Ds or I\+R sensors. Modern hardware, due to embedded micro processors etc., have less requirements on precise timing, and user space drivers are normally the preferred solution. One such driver consists of a C file, containing a number of function, which are linked into the executing program (e. g., Lircd). Traditionally (at least for L\+I\+R\+C) linking takes place during the build process (statically linking). The A\+P\+I for these drivers we will call \char`\"{}\+Driver A\+P\+I version 1\char`\"{}.

Dynamically loaded drivers was introduced L\+I\+R\+C just recently, {\itshape replacing} the statically linked drivers. It turned out to be necessary to slighty augment the driver A\+P\+I version 1. The new version will be referred to as \char`\"{}\+Driver A\+P\+I version 2\char`\"{}.

In this guide, the word {\itshape plugin} refers to the so-\/file on disk. Each such file contains one or more \hyperlink{structdriver}{driver(s)} visible in the user interface. 

\subsection*{Two flavors of drivers}

An I\+R signal consists of a sequence of on-\/times (pulses) and off-\/times (gaps). (We disregard modulation for the time being.) A full-\/fledged I\+R driver, on reading, can deliver the timing of these period (\char`\"{}durations\char`\"{}). On sending, it can be fed with a list of durations, and it sends these on-\/ and off-\/periods as (modulated) I\+R signals. Such a piece of hardware is suitable for receiving and/or transmitting \char`\"{}arbitrary\char`\"{} I\+R sequences.

Much I\+R hardware was not designed as general-\/purpose I\+R hardware, but to allow e.\+g. a laptop computer or a T\+V card to be be controlled by the supplied remote. This hardware in general decodes the I\+R signal in its own hardware, and delivers, for recognized signals, an integer code denoting the code received (like \char`\"{}play\char`\"{}). For signals not following the protocol, no output is generated. This property is indicated in the drivers as the feature {\ttfamily L\+I\+R\+C\+\_\+\+C\+A\+N\+\_\+\+R\+E\+C\+\_\+\+L\+I\+R\+C\+C\+O\+D\+E}.

As usable and flexible I\+R hardware for L\+I\+R\+C, these devices are second choice. The \char`\"{}learns\char`\"{} (configuration files) from such a device is of very limited value, and not portable to other I\+R devices, since timing information is missing. In the configuration file, this can be determined by the lines {\ttfamily one 0 0} and {\ttfamily one 0 0}, which is clearly not usable without the context, namely the hardware used for capturing.

This guide is intended for programmers writing and maintain \char`\"{}real\char`\"{} drivers.

At the time of writing, there are about 44 plugins and 54 drivers. Of the drivers, 13 are \char`\"{}general receivers\char`\"{}; the others are L\+I\+R\+C\+C\+O\+D\+E drivers. (The actual numbers vary depending on configuration i. e. libraries installed on the build system.) Since hardware related to L\+I\+R\+C\+C\+O\+D\+E drivers (typically a T\+V-\/card) normally doesn\textquotesingle{}t support sending there is no L\+I\+R\+C\+C\+O\+D\+E driver which can send data. 

The tool lirc-\/lsplugins can be used to generate overviews of the drivers and their capabilities. 

\subsection*{The C interface}

A (user space) driver is a C file where all the functions are declared {\ttfamily static}, i.\+e. not (directly) visible from outside of the file. The only thing visible from outside is a particular data structure, containing some data elements, and some pointers to functions, that in these way effectively are made public A\+P\+I. In this way a certain encapsulation is achieved. The data structure will be described next.

\subsubsection*{The {\ttfamily struct driver}}

The {\ttfamily struct driver} is the data structure representing the driver for L\+I\+R\+C. It is defined in {\ttfamily \hyperlink{driver_8h}{driver.\+h}} (in directory {\ttfamily lib}).


\begin{DoxyPre}
struct driver \{
        char *device;
        int fd;
        \_\_u32 features;
        \_\_u32 send\_mode;
        \_\_u32 rec\_mode;
        \_\_u32 code\_length;
        int (*init\_func) (void);
        int (*deinit\_func) (void);
        int (*send\_func) (struct ir\_remote* remote, struct ir\_ncode* code);
        char* (*rec\_func) (struct ir\_remote* remotes);
        int (*decode\_func) (struct ir\_remote* remote, struct decode\_ctx\_t* ctx);
        int (*drvctl\_func) (unsigned int cmd, void* arg);
         lirc\_t(*readdata) (lirc\_t timeout);
        char *name;
        unsigned int resolution;\end{DoxyPre}



\begin{DoxyPre}        /* The following fields are API version 2 extensions */
        const int api\_version;
        const char* driver\_version;
        const char* info;
        int (*const close\_func)(void);
        int (*const open\_func)(const char* device);
\};
    \end{DoxyPre}
 

These fields will next be described. Note that a driver sometimes \char`\"{}misuses\char`\"{} a field; e.\+g. the U\+D\+P driver expects a port number (as string) in the {\ttfamily device} field. 

Also note that some function pointer may be N\+U\+L\+L, indicating that the driver does not implement the said functionality (e.\+g. sending of I\+R signals).

The structures {\ttfamily \hyperlink{structir__remote}{ir\+\_\+remote}, \hyperlink{structir__ncode}{ir\+\_\+ncode}} and, {\ttfamily ir\+\_\+code} are declared in the file {\ttfamily \hyperlink{ir__remote__types_8h}{ir\+\_\+remote\+\_\+types.\+h}}. The data type {\ttfamily lirc\+\_\+t} (what a meaningful name!) is an integer value used in many places for storing timing data. It is defined by {\ttfamily \#define int} in {\ttfamily lirc.\+h}. 
\begin{DoxyDescription}
\item[device ]Typically the name of the device as text string in Linux. This corresponds to the {\ttfamily --device} argument to lircd Not all drivers respect the device field as input; some have hardcoded device name(s), some use autodetecting code. 


\item[fd ]A file descriptor associated with the driver.


\item[features ]Code for the features of the present device, see Appendix. It consist of the bitwise or of a number of possible features. 
\item[send\+\_\+mode ]Use {\ttfamily L\+I\+R\+C\+\_\+\+M\+O\+D\+E\+\_\+\+P\+U\+L\+S\+E}. 
\item[rec\+\_\+mode ]Use {\ttfamily L\+I\+R\+C\+\_\+\+M\+O\+D\+E\+\_\+\+M\+O\+D\+E2}. 
\item[code\+\_\+length ]Only of relevance for L\+I\+R\+C\+\_\+\+M\+O\+D\+E\+\_\+\+L\+I\+R\+C\+C\+O\+D\+E drivers, for which it is the size in bits of the L\+I\+R\+C\+C\+O\+D\+E. 
\item[init\+\_\+func ]Function pointer, see below. 
\item[deinit\+\_\+func ]Function pointer, see below. 
\item[send\+\_\+func]
\item[]Function pointer, see below. N\+U\+L\+L if the driver cannot transmit. 
\item[rec\+\_\+func]
\item[]Function pointer, see below. N\+U\+L\+L if the driver cannot receive. 
\item[decode\+\_\+func ]Function pointer, for \char`\"{}real\char`\"{} drivers (not using L\+I\+R\+C\+\_\+\+M\+O\+D\+E\+\_\+\+L\+I\+R\+C\+C\+O\+D\+E), just use {\ttfamily receive\+\_\+decode}, a function defined in {\ttfamily \hyperlink{receive_8c}{receive.\+c}}. 
\item[drvctl\+\_\+func ]Function pointer, see below. May be N\+U\+L\+L if there are no ioctls. 
\item[]
\item[readdata ]Function pointer, see below. Is N\+U\+L\+L if the driver reads uses L\+I\+R\+C\+\_\+\+M\+O\+D\+E\+\_\+\+L\+I\+R\+C\+C\+O\+D\+E. 
\item[name]
\item[]Name of the driver in a human readable form, as listed e.\+g. by {\ttfamily lircd --driver help} or {\ttfamily irrecord --driver help}. Although not enforced, it is recommended to use names following the syntax for C identifiers. 
\item[resolution ]The resolution in microseconds of the recorded durations when reading signals. Used as default value for the {\ttfamily aeps} parameter in remotes. 
\item[api\+\_\+version]
\item[]Use 2. 
\item[driver\+\_\+version ]Free form string used to identify the version of the driver, if desired. 
\item[info ]Free form string, overall driver information. 
\item[open\+\_\+func ]Function pointer, see below. 
\item[close\+\_\+func ]Function pointer, see below. 
\end{DoxyDescription}

\subsubsection*{Driver lifecycle and {\ttfamily lircd}}

The driver is loaded, used and unloaded by the executing program according to the following\+: 
\begin{DoxyEnumerate}
\item The program Lircd code determines what driver to use (normally the {\ttfamily --driver} runtime option) and invokes {\ttfamily \hyperlink{drv__admin_8c_a1eaff4902d2d278d2d42e47e763c89da}{hw\+\_\+choose\+\_\+driver()}} (in {\ttfamily \hyperlink{drv__admin_8c}{drv\+\_\+admin.\+c}}) which loads the driver and exposes the driver interface in the global variable {\ttfamily drv} (which is a {\ttfamily struct driver}). 
\item {\ttfamily Lircd} invokes the {\ttfamily open\+\_\+func()} which establishes the device to use, usually based on the runtime option {\ttfamily --device}. 
\item When a client connects, either for sending or receiving, the function {\ttfamily init\+\_\+func()} is invoked, initializing the driver. In some drivers, the capabilities of the drivers, i.\+e. the field {\ttfamily features}, are available only after initializing. The driver also exports the {\ttfamily fd} field, a file descriptor (a positive int) for the underlying file. 
\item From this point, calls to {\ttfamily read\+\_\+func()} and {\ttfamily send\+\_\+func()} are possible. 
\item When the last client is terminated, executing program calls {\ttfamily deinit\+\_\+func()}. Note that the Lircd program may need the device again e.\+g., if another sending request is received, so a hard closing of a device may not be optimal here. 
\item As a last operation, executing program should call the {\ttfamily close\+\_\+func()}. This relinquishes all resources allocated by the driver. 
\item Calls to {\ttfamily drvctl\+\_\+func()} are possible at any time. They are the responsibility of the programmer. In particular, ioctl operations may fail under some circumstances. 
\item The associated functions are not guaranteed to be executed in the order described. In general, the driver should not break if e.\+g., the {\ttfamily init\+\_\+func()} is called on an already open device, or {\ttfamily deinit\+\_\+func()} called on a device not open. 
\end{DoxyEnumerate}

\subsubsection*{Driver structure}

Typical structure of a driver file will be shown next.


\begin{DoxyPre}
/* Include system includes files as needed */\end{DoxyPre}



\begin{DoxyPre}\# 211 "/home/mk/tmp/lirc/lib/driver\_api.dox" 2 /* The overall include, mandatory, often sufficient.  */
\# 212 "/home/mk/tmp/lirc/lib/driver\_api.dox" 2      /* For drivers using serial hardware. */\end{DoxyPre}



\begin{DoxyPre}/* Global (but "static") variable definition. */\end{DoxyPre}



\begin{DoxyPre}/* static function definitions. */
static int generic\_init() \{
    /* Open device/hardware */\end{DoxyPre}



\begin{DoxyPre}    \hyperlink{group__driver__api_ga85a7e2c6a62aab93aaa6453dea381112}{send\_buffer\_init()};
    return 1;
\}\end{DoxyPre}



\begin{DoxyPre}static int generic\_deinit(void) \{
    /* close device */
    return 1;
\}\end{DoxyPre}



\begin{DoxyPre}static int generic\_send(struct ir\_remote* remote, struct ir\_ncode* code) \{
    result = send\_buffer\_put(remote, code);
    if (!result)
        return 0;\end{DoxyPre}



\begin{DoxyPre}    /* Payload signal is now available in global variable send\_buf. */
    /* Process sendbuf (see \hyperlink{transmit_8h}{transmit.h}). */
    return success;
\}\end{DoxyPre}



\begin{DoxyPre}static char *rec\_func(struct ir\_remote* remotes) \{
    if (!rec\_buffer\_clear) \{
        /* handle errors */
        return NULL;
    \}
    return decode\_all(remotes);
\}\end{DoxyPre}



\begin{DoxyPre}static char *decode\_func(struct ir\_remote* remote, struct decode\_ctx\_t* ctx) \{
    return receive\_decode(remote, ctx);
\}\end{DoxyPre}



\begin{DoxyPre}static int generic\_drvctl(unsigned int cmd, void *arg) \{
    /* Do something device specific, e.g.
       return ioctl(drv.fd, cmd, arg); */
    return cmd == 42 ? 1 : 0;
\}\end{DoxyPre}



\begin{DoxyPre}static lirc\_t *readdata(lirc\_t timeout) \{
    /* compute and return the next duration in microseconds */
\}\end{DoxyPre}



\begin{DoxyPre}struct driver my\_driver = \{
   /* see above. */
\}\end{DoxyPre}



\begin{DoxyPre}struct driver* hardwares[] = \{ \&my\_hardware, NULL \};
    \end{DoxyPre}
 \paragraph*{Syntax and semantics of the functions}

Note that, even if implementing the functions in C++, there is no need to declare them as {\ttfamily external \char`\"{}\+C\char`\"{}}.

\subparagraph*{{\ttfamily init\+\_\+func}}

{\ttfamily int myinit\+\_\+func(void)} 

Function called for initializing the driver and the hardware. It should return nonzero in the case of success. This function simple opens the device. In addition, the functions {\ttfamily \hyperlink{group__driver__api_gabc294def4957afc161909b72e1348835}{rec\+\_\+buffer\+\_\+init(void)}} and/or {\ttfamily \hyperlink{group__driver__api_ga85a7e2c6a62aab93aaa6453dea381112}{send\+\_\+buffer\+\_\+init(void)}} needs to be called.

\subparagraph*{{\ttfamily deinit\+\_\+func}}

{\ttfamily int mydeinit\+\_\+func(void)} 

Function called for suspending the driver. Zero return value indicates failure, all other return values success.

\subparagraph*{{\ttfamily send\+\_\+func}}

{\ttfamily int mysend\+\_\+func(struct ir\+\_\+remote $\ast$remote, struct ir\+\_\+ncode $\ast$code)} 

Function called for sending an I\+R code, residing in the second argument. For this, the function {\ttfamily \hyperlink{group__driver__api_ga0d43b932c9b39d14e675dbd9507f3997}{send\+\_\+buffer\+\_\+put(struct ir\+\_\+remote $\ast$remote, struct ir\+\_\+ncode $\ast$code)}} is called, with the same arguments. This makes the global variable {\ttfamily send\+\_\+bug} containing the durations in micro seconds for the I\+R signal. The field {\ttfamily data} is a pointer to {\ttfamily wptr} number of numbers, having the data type {\ttfamily lirc\+\_\+t}. Returns non-\/zero if operation successful.

Called from {\ttfamily \hyperlink{ir__remote_8c}{ir\+\_\+remote.\+c}}.

\subparagraph*{{\ttfamily rec\+\_\+func}}

{\ttfamily char$\ast$ myrec\+\_\+func(struct ir\+\_\+remote$\ast$ remotes)} 

The canonical implementation for non-\/\+L\+I\+R\+C\+C\+O\+D\+E drivers is 


\begin{DoxyPre}
        if (!rec\_buffer\_clear) \{
            /* handle errors */
            return NULL;
        \}
        return decode\_all(remotes);
  \end{DoxyPre}
 This is a non-\/blocking function which returns N\+U\+L\+L if there is no data available currently, but might very well succeed later. The device might get closed as part of error handling, so calling code should be prepared to reopen device if required. \subparagraph*{{\ttfamily decode\+\_\+func}}

{\ttfamily char {\itshape mydecode\+\_\+func(struct \hyperlink{structir__remote}{ir\+\_\+remote} $\ast$ remote, struct \hyperlink{structdecode__ctx__t}{decode\+\_\+ctx\+\_\+t}} ctx)} 

For non-\/\+L\+I\+R\+C\+\_\+\+M\+O\+D\+E\+\_\+\+L\+I\+R\+C\+C\+O\+D\+E, just call {\ttfamily receive\+\_\+decode}, or write {\ttfamily receive\+\_\+decode} directly in the {\ttfamily struct driver}. \subparagraph*{{\ttfamily drvctl\+\_\+func}}

{\ttfamily mydrvctl\+\_\+func(unsigned int cmd, void $\ast$arg)} 

Depending on the particular driver and hardware, additional functionality can be implemented here, with semantics as determined by the driver. There are some cmd definitions in \hyperlink{driver_8h}{driver.\+h} which could be used by any driver. Driver-\/specific cmd constants should be $>$ D\+R\+V\+C\+T\+L\+\_\+\+M\+A\+X.

drvctl() returns 0 if O\+K, else a positive error code some of which defined in \hyperlink{driver_8h}{driver.\+h} 

\hyperlink{driver_8h}{driver.\+h} defines the D\+R\+V\+C\+T\+L\+\_\+\+S\+E\+T\+\_\+\+O\+P\+T\+I\+O\+N cmd. This is a generic way to set a named key to value which should cover many (most?) needs for the drvctl() function. 

\subparagraph*{{\ttfamily readdata}}

{\ttfamily lirc\+\_\+t myreaddata(lirc\+\_\+t timeout)} 

This function returns one integer of read information from the device. For this, it may wait for a time determined by the argument, in micro seconds. The return value has the semantic of a duration (pulse or gap) in microseconds. For this reason, 0 is an \char`\"{}impossible\char`\"{} value, and would indicate an error. In L\+I\+R\+C, only the lower 24 bits are used for the length of the duration (making the largest duration that L\+I\+R\+C can represent 2$^\wedge$24 -\/ 1 = 16777215 microseconds). See the example code.

The function is called from the daemon Lircd as well as from irrecord, and mode2.

\subparagraph*{{\ttfamily close\+\_\+func}}

{\ttfamily int close\+\_\+func(void)} 

Hard close of the device. zero return value indicates success, other values indicates an error. Some standard error codes are defined in \hyperlink{driver_8h}{driver.\+h}.

\subparagraph*{{\ttfamily open\+\_\+func}}

{\ttfamily int open\+\_\+func(void)} 

Open the device. This is the basic, possibly expensive steps taken to make the device usable. Returns 0 on success, else an error code, some of which defined in \hyperlink{driver_8h}{driver.\+h}.

When running using the effective-\/user option, this function is called running as root -\/ other functions are called running as the effective-\/user optionn. 

\paragraph*{Comments}


\begin{DoxyItemize}
\item Since no elements are exported, except for through the {\ttfamily hardwares} array, an associated header file ({\ttfamily .h}-\/file) is neither necessary nor desired. (The only exception would be special constants for usage with the drvctl function.) 
\item In the interest of portability and encapsulation, the only L\+I\+R\+C files that should be included are {\ttfamily \hyperlink{lirc__driver_8h}{lirc\+\_\+driver.\+h}} (which includes {\ttfamily \hyperlink{driver_8h}{driver.\+h}, \hyperlink{lirc__log_8h}{lirc\+\_\+log.\+h}, \hyperlink{receive_8h}{receive.\+h}}, i and {\ttfamily \hyperlink{transmit_8h}{transmit.\+h}}) and if required also {\ttfamily \hyperlink{serial_8h}{serial.\+h}}. Inclusions of other L\+I\+R\+C files (including {\ttfamily config.\+h}) should be avoided. 
\item The L\+I\+R\+C name of the driver is taken from the {\ttfamily name} field of the {\ttfamily hardware} struct. The file name is thus irrelevant. For files containing only one driver, it is recommended to keep the name of the file equal to the name of the driver (with added file extension). 
\end{DoxyItemize}

\subsubsection*{Generating console output}

It is possible to generate console output in any way; writing on {\ttfamily stdout} or {\ttfamily stderr}, using e.\+g. stdio or C++ streams. However, to conform with the working of the rest of L\+I\+R\+C, it is recommended to use only the functions {\ttfamily void logprintf(int prio, const char $\ast$format\+\_\+str, ...)} and {\ttfamily void logperror (int prio, const char $\ast$s)}, which are declared in the header {\ttfamily \hyperlink{lirc__log_8h}{lirc\+\_\+log.\+h}}.

\subsubsection*{Timing issues}

\paragraph*{Sending}

The daemon {\ttfamily Lircd} takes care of the timing between the I\+R sequences, calling the {\ttfamily send\+\_\+func} as it sees fit. Also, the final gap is the responsibility of Lircd. For example, if a signal is to be sent repeatedly every {\itshape x} milliseconds, {\ttfamily Lircd} will take care of the timing, at least as long as {\ttfamily send\+\_\+func} does not consume too much time.

\paragraph*{Receiving}

Except for the timeout argument to {\ttfamily readdata}, there does not appear to be any timing issues the driver author needs to address.

\subsubsection*{Compiling}

\paragraph*{Compiling in-\/tree}

To compile in-\/tree and assuming autogen.\+sh and ./configure has been run just copy the plugin source code to the plugins directory and run 
\begin{DoxyPre}
    \$ cd plugins;
    \$ ./make-pluginlist.sh > pluginlist.am
    \$ make
\end{DoxyPre}
 \paragraph*{Compiling out-\/of-\/tree}

Plugins can also easily be built out-\/of tree. Only some include files from L\+I\+R\+C are needed. Just a trivial compilation is needed. A simple generic Makefile is provided in the Appendix, another example is available in the sources as \hyperlink{drivers_2default_2Makefile-example}{drivers/default/\+Makefile}. The autotools are not needed, in particular not libtool.

\subsubsection*{The anatomy of a complete driver package.}

A complete driver package consists of three files\+: the driver code, the configuration support and the documentation.


\begin{DoxyPre}
lirc
 |
 |-----doc
 |      |
 |      |
 |     html-source------
 |                     |
 |               foo\_driver.html
 |-----configs
 |        |
 |     foo.conf
 |
 |----plugins
          |
       foo.so
\end{DoxyPre}
 

The driver code has been described all over in this document. There is also plenty of examples in the plugins/ directory. The compiled .so file could just be dropped into a directory in the -\/\+U/--plugins search path which basically could be anywhere.

The configuration support is a single file in the configs/ directory. The file configs/\+R\+E\+A\+D\+M\+E describes the format. This is used by tools like lirc-\/setup, but also to create the list of all drivers. New files are automatically picked up.

The documentation is a single html file in the doc/html-\/source directory. The filename should have \+\_\+driver.\+html suffix. New files with this suffix are automatically picked up by the build system, as long it\textquotesingle{}s listed in doc/\+Makefile.\+am.

The lirc-\/driver pkgconfig file defines three variables useful when installing files\+: {\itshape plugindir}, {\itshape configdir} and {\itshape plugindocs}. These are the configured locations for each file. E. g., to get the plugindir location 
\begin{DoxyPre}
        \$ pkg-config --variable=plugindir lirc-driver
        /usr/lib64/lirc/plugins
\end{DoxyPre}


\subsubsection*{Using C++}

Plugins can also be written in C++. The used include files are required to be \char`\"{}\+C++-\/safe\char`\"{} i. e., the functions to be called from C++ have to be declared {\ttfamily extern \char`\"{}\+C\char`\"{}}, to make sure that the generated code follows C\textquotesingle{}s calling conventions. Since the plugin code is called only indirectly through the hardware struct, no {\ttfamily extern \char`\"{}\+C\char`\"{}} declarations are required in the plugin code. 

\paragraph*{Adding additional libraries}

Extra libraries, as well as include files, can be simply added to the Makefile (or Makefile.\+am for the case of in-\/tree builds). Note that for libraries located outside of the \char`\"{}standard\char`\"{} directories, it may be required to use an {\ttfamily -\/\+L} and an {\ttfamily -\/rpath} argument to the linker arguments. See the Makefile in Appendix 2.

\subsection*{Appendix. List of features ({\ttfamily lirc.\+h}).}

There are four \char`\"{}modes of operation\char`\"{} of L\+I\+R\+C\+: L\+I\+R\+C\+\_\+\+M\+O\+D\+E\+\_\+\+R\+A\+W, L\+I\+R\+C\+\_\+\+M\+O\+D\+E\+\_\+\+P\+U\+L\+S\+E, L\+I\+R\+C\+\_\+\+M\+O\+D\+E\+\_\+\+M\+O\+D\+E2, L\+I\+R\+C\+\_\+\+M\+O\+D\+E\+\_\+\+L\+I\+R\+C\+C\+O\+D\+E. In the current code, no semantic difference between the first three can be inferred. For the meaning of the last, see above (\char`\"{}\+Two flavors of drivers\char`\"{}).

There are a number of \char`\"{}features\char`\"{} that a driver can have or not have. These are documented in the \href{lirc.html}{\tt lirc(4)} manpage.

\subsection*{Appendix 2. Generic Makefile}


\begin{DoxyPre}\end{DoxyPre}



\begin{DoxyPre}LIRC\_SRC=/home/bengt/lirc/master\end{DoxyPre}



\begin{DoxyPre}PLUGINDIR := /home/bengt/lirc/root/lib/lirc/plugins\end{DoxyPre}



\begin{DoxyPre}MACHINE := -m64
INCLUDE := -I/lib -I 
OPTIMIZE := -O2
DEBUG := -g
SHARED :=-shared -fPIC
WARNINGS=-Wall
CC := gcc
CPP := g++\end{DoxyPre}



\begin{DoxyPre}\%.so: \%.c
                -o \$@ \$< \end{DoxyPre}



\begin{DoxyPre}\%.so: \%.cpp
               -o \$@ \$< \end{DoxyPre}



\begin{DoxyPre}default:
         "There is no default target in this makefile."
         "Type \(\backslash\)"make plugin.so" to compile the plugin named plugin,"
        @echo "and "make install" to install it"\end{DoxyPre}



\begin{DoxyPre}install:
        cp *.so \end{DoxyPre}



\begin{DoxyPre}clean:
        rm -f *.so\end{DoxyPre}



\begin{DoxyPre}\end{DoxyPre}




 