--- /dev/null
+Linux Infrared Remote Control - use an easy to build home-brewn IR-receiver, an
+(almost) arbitrary remote control and control your Linux box with it! More
+about it at www.lirc.org. Be sure to read LIRC documentation before going ahead
+in this README.
+
+If you have installed the lirc-package, configure will autodetect it. If LIRC
+support is enabled and an error occurs Geeqie will tell you on startup. The
+application name for Geeqie is geeqie. Here is the list of supported commands:
+
+DOWN [int] - Move "camera" down by the specified amount. Default=1
+EXIT - Exit Geeqie
+FIRST - Jump to first image
+INFO - Show image information (full screen only)
+LAST - Jump to last image
+LEFT [int] - Move "camera" left by the specified amount. Default=1
+NEXT - Go to next image
+PAUSE - Pause/unpause slideshow
+PREV - Go to previous image
+RIGHT [int] - Move "camera" right by the specified amount. Default=1
+ROTATE_90 - Rotate image 90 degrees clockwise.
+ROTATE_90_CC - Rotate image 90 degrees counter-clockwise.
+SET_INV_ZOOM [int] - Zoom to 1/Nx. Deafult=1x
+SET_ZOOM [int] - Zoom to Nx. Default=1x
+UP [int] - Move "camera" up by the specified amount. Default=1
+ZOOM_IN [int] - Zoom in. Value specifies the amount of zoom.
+ZOOM_MAX - Zoom to fit image
+ZOOM_OUT [int] - Zoom out. Value specifies the amount of zoom.
+
+Don't forget to enable the repeat flag in .lircrc when it make sense
+(directional buttons, zoom in and out, ...)
+Here's an excerpt from my .lircrc:
+
+begin geeqie
+ begin
+ prog = geeqie
+ button = vol_up
+ config = ZOOM_IN 1
+ repeat = 3
+ end
+ begin
+ prog = geeqie
+ button = vol_down
+ config = ZOOM_OUT 1
+ repeat = 3
+ end
+ begin
+ prog = geeqie
+ button = down
+ config = DOWN 10
+ repeat = 1
+ end
+ begin
+ prog = geeqie
+ button = up
+ config = UP 10
+ repeat = 1
+ end
+ begin
+ prog = geeqie
+ button = right
+ config = RIGHT 10
+ repeat = 1
+ end
+ begin
+ prog = geeqie
+ button = left
+ config = LEFT 10
+ repeat = 1
+ end
+ begin
+ prog = geeqie
+ button = back
+ config = PREV
+ end
+ begin
+ prog = geeqie
+ button = forw
+ config = NEXT
+ end
+ begin
+ prog = geeqie
+ button = skip_back
+ config = FIRST
+ end
+ begin
+ prog = geeqie
+ button = skip_forw
+ config = LAST
+ end
+ begin
+ prog = geeqie
+ button = pause
+ config = PAUSE
+ end
+ begin
+ prog = geeqie
+ button = surround
+ config = SET_ZOOM
+ end
+ begin
+ prog = geeqie
+ button = 1
+ config = ROTATE_90
+ end
+ begin
+ prog = geeqie
+ button = 2
+ config = ROTATE_90_CC
+ end
+ begin
+ prog = geeqie
+ button = 3
+ config = INFO
+ end
+ begin
+ prog = geeqie
+ button = 4
+ config = EXIT
+ end
+end geeqie
+
+At the moment Geeqie uses the standard location for the lirc-config file
+(~/.lircrc).
+
+LIRC support and documentation by Matteo Beniamino
+<beniamino@tautologica.org>.
+
+(This file is 'inspired' by LIRC documentation from mplayer).
--- /dev/null
+#include "lirc.h"
+
+#ifdef HAVE_LIRC
+#include <lirc/lirc_client.h>
+#include "layout_image.h"
+#include "debug.h"
+
+gint lirc_fd = -1;
+struct lirc_config *config = NULL;
+guint input_tag;
+GIOChannel *gio_chan;
+
+/*
+ *-----------------------------------------------------------------------------
+ * LIRC callback
+ *-----------------------------------------------------------------------------
+ */
+
+void lirc_cleanup()
+{
+ if (config)
+ {
+ gtk_input_remove(input_tag);
+ lirc_freeconfig(config);
+ config = NULL;
+ }
+ if (lirc_fd != -1)
+ {
+ lirc_deinit();
+ lirc_fd = -1;
+ }
+ if (gio_chan)
+ {
+ g_io_channel_close(gio_chan);
+ }
+}
+
+gboolean lirc_input_callback(GIOChannel *source, GIOCondition condition,
+ gpointer data)
+{
+ LayoutWindow *lw = data;
+ gchar *ptr;
+ gint ret;
+ gint x = 0;
+ gint y = 0;
+
+ /* LIRC code and corresponding geeqie command (and parameters)*/
+ gchar *code;
+ gchar *cmd;
+
+ /* parameters for geeqie command */
+ gint i_parm;
+ gfloat fl_parm;
+
+ while ((ret = lirc_nextcode(&code)) == 0 && code)
+ {
+ while ((ret = lirc_code2char(config, code, &cmd)) == 0 && cmd)
+ {
+ if (g_strncasecmp("LEFT", cmd, 4) == 0)
+ {
+ ptr = cmd + 4;
+ while (g_ascii_isspace(*ptr)) ptr++;
+ i_parm = atoi(ptr);
+
+ if (i_parm <= 0) i_parm = 1;
+ x -= i_parm;
+ }
+ else if (g_strncasecmp("RIGHT", cmd, 5) == 0)
+ {
+ ptr = cmd + 5;
+ while (g_ascii_isspace(*ptr)) ptr++;
+ i_parm = atoi(ptr);
+
+ if (i_parm <= 0) i_parm = 1;
+ x += i_parm;
+ }
+ else if (g_strncasecmp("UP", cmd, 2) == 0)
+ {
+ ptr = cmd + 2;
+ while (g_ascii_isspace(*ptr)) ptr++;
+ i_parm = atoi(ptr);
+
+ if (i_parm <= 0) i_parm = 1;
+ y -= i_parm;
+ }
+ else if (g_strncasecmp("DOWN", cmd, 4) == 0)
+ {
+ ptr = cmd + 4;
+ while (g_ascii_isspace(*ptr)) ptr++;
+ i_parm = atoi(ptr);
+
+ if (i_parm <= 0) i_parm = 1;
+ y += i_parm;
+ }
+ else if (g_strcasecmp("PREV", cmd) == 0)
+ {
+ layout_image_prev(lw);
+ }
+ else if (g_strcasecmp("NEXT", cmd) == 0)
+ {
+ layout_image_next(lw);
+ }
+ else if (g_strncasecmp("ZOOM_IN", cmd, 7) == 0)
+ {
+ ptr = cmd + 7;
+ while (g_ascii_isspace(*ptr)) ptr++;
+ fl_parm = atoi(ptr) / 10.0;
+
+ if (fl_parm <= 0.01) fl_parm = get_zoom_increment();
+ layout_image_zoom_adjust(lw, fl_parm);
+ }
+ else if (g_strncasecmp("ZOOM_OUT", cmd, 8) == 0)
+ {
+ ptr = cmd + 8;
+ while (g_ascii_isspace(*ptr)) ptr++;
+ fl_parm = atoi(ptr) / 10.0;
+
+ if (fl_parm <= 0.01) fl_parm = get_zoom_increment();
+ layout_image_zoom_adjust(lw, -fl_parm);
+ }
+ else if (g_strcasecmp("ZOOM_MAX", cmd) == 0)
+ {
+ layout_image_zoom_set(lw, 0.0);
+ }
+ else if (g_strncasecmp("SET_ZOOM", cmd, 8) == 0)
+ {
+ ptr = cmd + 8;
+ while (g_ascii_isspace(*ptr)) ptr++;
+ i_parm = atoi(ptr);
+
+ if (i_parm <= 0) i_parm = 1;
+ layout_image_zoom_set(lw, 1.0);
+ }
+ else if (g_strncasecmp("SET_INV_ZOOM", cmd, 12) == 0)
+ {
+ ptr = cmd + 12;
+ while (g_ascii_isspace(*ptr)) ptr++;
+ i_parm = atoi(ptr);
+
+ if (i_parm <= 0) i_parm = 1;
+ layout_image_zoom_set(lw, -i_parm);
+ }
+ else if (g_strcasecmp("FIRST", cmd) == 0)
+ {
+ layout_image_first(lw);
+ }
+ else if (g_strcasecmp("LAST", cmd) == 0)
+ {
+ layout_image_last(lw);
+ }
+ else if (g_strcasecmp("PAUSE", cmd) == 0)
+ {
+ layout_image_slideshow_pause_toggle(lw);
+ }
+ else if (g_strcasecmp("ROTATE_90", cmd) == 0)
+ {
+ layout_image_alter(lw, ALTER_ROTATE_90);
+ }
+ else if (g_strcasecmp("ROTATE_90_CC", cmd) == 0)
+ {
+ layout_image_alter(lw, ALTER_ROTATE_90_CC);
+ }
+ else if (g_strcasecmp("INFO", cmd) == 0)
+ {
+ layout_image_overlay_toggle(lw);
+ }
+ else if (g_strcasecmp("EXIT", cmd) == 0)
+ {
+ exit_program();
+ }
+ }
+ free(code);
+ if (ret == -1) break;
+ }
+ if (x != 0 || y!= 0)
+ {
+ layout_image_scroll(lw, x, y);
+ }
+
+ if (ret == -1)
+ {
+ /* something went badly wrong */
+ fprintf(stderr, _("disconnected from LIRC\n"));
+ lirc_cleanup();
+ return (gboolean)FALSE;
+ }
+ return (gboolean)TRUE;
+}
+
+void layout_image_lirc_init(LayoutWindow *lw)
+{
+ int flags;
+
+ DEBUG_1("Initializing LIRC...");
+ lirc_fd = lirc_init(GQ_APPNAME_LC, get_debug_level() > 0);
+ if (lirc_fd == -1)
+ {
+ fprintf(stderr, _("Could not init LIRC support\n"));
+ return;
+ }
+ if (lirc_readconfig(NULL, &config, NULL) == -1)
+ {
+ lirc_deinit();
+ fprintf(stderr,
+ _("could not read LIRC config file\n"
+ "please read the documentation of LIRC to \n"
+ "know how to create a proper config file\n"));
+ return;
+ }
+ gio_chan = g_io_channel_unix_new(lirc_fd);
+ input_tag = g_io_add_watch(gio_chan, G_IO_IN,
+ lirc_input_callback, lw);
+ fcntl(lirc_fd, F_SETOWN, getpid());
+ flags = fcntl(lirc_fd, F_GETFL, 0);
+ if (flags != -1) fcntl(lirc_fd, F_SETFL, flags|O_NONBLOCK);
+ fflush(stderr);
+}
+
+#endif /* HAVE_LIRC */