1 /*
2 * Copyright (C) 2008 - 2016 The Geeqie Team
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17 */
18
19 #include <glib/gprintf.h>
20
21 #include "lirc.h"
22
23 #include "misc.h"
24
25 #ifdef HAVE_LIRC
26 #include <lirc/lirc_client.h>
27 #include "layout_image.h"
28
29 gint lirc_fd = -1;
30 struct lirc_config *config = NULL;
31 guint input_tag = 0; /* event source id */
32 GIOChannel *gio_chan;
33
34 /*
35 *-----------------------------------------------------------------------------
36 * LIRC callback
37 *-----------------------------------------------------------------------------
38 */
39
lirc_cleanup(void)40 static void lirc_cleanup(void)
41 {
42 if (config)
43 {
44 g_source_remove(input_tag);
45 lirc_freeconfig(config);
46 config = NULL;
47 }
48 if (lirc_fd != -1)
49 {
50 lirc_deinit();
51 lirc_fd = -1;
52 }
53 if (gio_chan)
54 {
55 g_io_channel_shutdown(gio_chan, TRUE, NULL);
56 g_io_channel_unref(gio_chan);
57 }
58 }
59
lirc_input_callback(GIOChannel * source,GIOCondition condition,gpointer data)60 static gboolean lirc_input_callback(GIOChannel *source, GIOCondition condition,
61 gpointer data)
62 {
63 LayoutWindow *lw = data;
64 gchar *ptr;
65 gint ret;
66 gint x = 0;
67 gint y = 0;
68
69 /* LIRC code and corresponding geeqie command (and parameters)*/
70 gchar *code;
71 gchar *cmd;
72
73 /* parameters for geeqie command */
74 gint i_parm;
75 gfloat fl_parm;
76
77 while ((ret = lirc_nextcode(&code)) == 0 && code)
78 {
79 while ((ret = lirc_code2char(config, code, &cmd)) == 0 && cmd)
80 {
81 if (g_ascii_strncasecmp("LEFT", cmd, 4) == 0)
82 {
83 ptr = cmd + 4;
84 while (g_ascii_isspace(*ptr)) ptr++;
85 i_parm = atoi(ptr);
86
87 if (i_parm <= 0) i_parm = 1;
88 x -= i_parm;
89 }
90 else if (g_ascii_strncasecmp("RIGHT", cmd, 5) == 0)
91 {
92 ptr = cmd + 5;
93 while (g_ascii_isspace(*ptr)) ptr++;
94 i_parm = atoi(ptr);
95
96 if (i_parm <= 0) i_parm = 1;
97 x += i_parm;
98 }
99 else if (g_ascii_strncasecmp("UP", cmd, 2) == 0)
100 {
101 ptr = cmd + 2;
102 while (g_ascii_isspace(*ptr)) ptr++;
103 i_parm = atoi(ptr);
104
105 if (i_parm <= 0) i_parm = 1;
106 y -= i_parm;
107 }
108 else if (g_ascii_strncasecmp("DOWN", cmd, 4) == 0)
109 {
110 ptr = cmd + 4;
111 while (g_ascii_isspace(*ptr)) ptr++;
112 i_parm = atoi(ptr);
113
114 if (i_parm <= 0) i_parm = 1;
115 y += i_parm;
116 }
117 else if (g_ascii_strcasecmp("PREV", cmd) == 0)
118 {
119 layout_image_prev(lw);
120 }
121 else if (g_ascii_strcasecmp("NEXT", cmd) == 0)
122 {
123 layout_image_next(lw);
124 }
125 else if (g_ascii_strncasecmp("ZOOM_IN", cmd, 7) == 0)
126 {
127 ptr = cmd + 7;
128 while (g_ascii_isspace(*ptr)) ptr++;
129 fl_parm = atoi(ptr) / 10.0;
130
131 if (fl_parm <= 0.01) fl_parm = get_zoom_increment();
132 layout_image_zoom_adjust(lw, fl_parm, FALSE);
133 }
134 else if (g_ascii_strncasecmp("ZOOM_OUT", cmd, 8) == 0)
135 {
136 ptr = cmd + 8;
137 while (g_ascii_isspace(*ptr)) ptr++;
138 fl_parm = atoi(ptr) / 10.0;
139
140 if (fl_parm <= 0.01) fl_parm = get_zoom_increment();
141 layout_image_zoom_adjust(lw, -fl_parm, FALSE);
142 }
143 else if (g_ascii_strcasecmp("ZOOM_MAX", cmd) == 0)
144 {
145 layout_image_zoom_set(lw, 0.0, FALSE);
146 }
147 else if (g_ascii_strcasecmp("FULL_SCREEN", cmd) == 0)
148 {
149 layout_image_full_screen_toggle(lw);
150 }
151 else if (g_ascii_strncasecmp("SET_ZOOM", cmd, 8) == 0)
152 {
153 ptr = cmd + 8;
154 while (g_ascii_isspace(*ptr)) ptr++;
155 i_parm = atoi(ptr);
156
157 if (i_parm <= 0) i_parm = 1;
158 layout_image_zoom_set(lw, 1.0, FALSE);
159 }
160 else if (g_ascii_strncasecmp("SET_INV_ZOOM", cmd, 12) == 0)
161 {
162 ptr = cmd + 12;
163 while (g_ascii_isspace(*ptr)) ptr++;
164 i_parm = atoi(ptr);
165
166 if (i_parm <= 0) i_parm = 1;
167 layout_image_zoom_set(lw, -i_parm, FALSE);
168 }
169 else if (g_ascii_strcasecmp("FIRST", cmd) == 0)
170 {
171 layout_image_first(lw);
172 }
173 else if (g_ascii_strcasecmp("LAST", cmd) == 0)
174 {
175 layout_image_last(lw);
176 }
177 else if (g_ascii_strcasecmp("PAUSE", cmd) == 0)
178 {
179 layout_image_slideshow_pause_toggle(lw);
180 }
181 else if (g_ascii_strcasecmp("ROTATE_90", cmd) == 0)
182 {
183 layout_image_alter_orientation(lw, ALTER_ROTATE_90);
184 }
185 else if (g_ascii_strcasecmp("ROTATE_90_CC", cmd) == 0)
186 {
187 layout_image_alter_orientation(lw, ALTER_ROTATE_90_CC);
188 }
189 else if (g_ascii_strcasecmp("INFO", cmd) == 0)
190 {
191 layout_image_overlay_toggle(lw);
192 }
193 else if (g_ascii_strcasecmp("EXIT", cmd) == 0)
194 {
195 exit_program();
196 }
197 }
198 free(code);
199 if (ret == -1) break;
200 }
201 if (x != 0 || y != 0)
202 {
203 layout_image_scroll(lw, x, y, FALSE);
204 }
205
206 if (ret == -1)
207 {
208 /* something went badly wrong */
209 g_fprintf(stderr, _("disconnected from LIRC\n"));
210 lirc_cleanup();
211 return (gboolean)FALSE;
212 }
213 return (gboolean)TRUE;
214 }
215
layout_image_lirc_init(LayoutWindow * lw)216 void layout_image_lirc_init(LayoutWindow *lw)
217 {
218 gint flags;
219 gboolean lirc_verbose = (get_debug_level() >= 2);
220
221 lirc_fd = lirc_init(GQ_APPNAME_LC, lirc_verbose);
222 if (lirc_fd == -1)
223 {
224 DEBUG_1("Initializing LIRC... failed");
225 return;
226 }
227
228 DEBUG_1("Initializing LIRC... OK");
229 if (lirc_readconfig(NULL, &config, NULL) == -1)
230 {
231 lirc_deinit();
232
233 g_fprintf(stderr,
234 _("could not read LIRC config file\n"
235 "please read the documentation of LIRC to \n"
236 "know how to create a proper config file\n"));
237 fflush(stderr);
238
239 DEBUG_1("Failed to read LIRC config file");
240 return;
241 }
242 if (lirc_verbose) fflush(stderr);
243
244 gio_chan = g_io_channel_unix_new(lirc_fd);
245 input_tag = g_io_add_watch(gio_chan, G_IO_IN,
246 lirc_input_callback, lw);
247 fcntl(lirc_fd, F_SETOWN, getpid());
248 flags = fcntl(lirc_fd, F_GETFL, 0);
249 if (flags != -1) fcntl(lirc_fd, F_SETFL, flags|O_NONBLOCK);
250 }
251
252 #endif /* HAVE_LIRC */
253 /* vim: set shiftwidth=8 softtabstop=0 cindent cinoptions={1s: */
254