1
/* LIBGIMP - The GIMP Library
2
* Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
1
/* GIMP - The GNU Image Manipulation Program
2
* Copyright (C) 1995-1997 Spencer Kimball and Peter Mattis
4
4
* controller_linux_input.c
5
* Copyright (C) 2004 Sven Neumann <sven@gimp.org>
7
* This library is free software; you can redistribute it and/or
8
* modify it under the terms of the GNU Lesser General Public
9
* License as published by the Free Software Foundation; either
10
* version 2 of the License, or (at your option) any later version.
12
* This library is distributed in the hope that it will be useful,
5
* Copyright (C) 2004-2007 Sven Neumann <sven@gimp.org>
6
* Michael Natterer <mitch@gimp.org>
8
* This program is free software; you can redistribute it and/or modify
9
* it under the terms of the GNU General Public License as published by
10
* the Free Software Foundation; either version 2 of the License, or
11
* (at your option) any later version.
13
* This program is distributed in the hope that it will be useful,
13
14
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15
* Lesser General Public License for more details.
15
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
* GNU General Public License for more details.
17
* You should have received a copy of the GNU Lesser General Public
18
* License along with this library; if not, write to the
19
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20
* Boston, MA 02111-1307, USA.
18
* You should have received a copy of the GNU General Public License
19
* along with this program; if not, write to the Free Software
20
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23
23
#include "config.h"
67
72
{ BTN_SIDE, "button-side", N_("Button Side") },
68
73
{ BTN_EXTRA, "button-extra", N_("Button Extra") },
69
74
{ BTN_FORWARD, "button-forward", N_("Button Forward") },
70
{ BTN_BACK, "button-back", N_("Button Forward") },
75
{ BTN_BACK, "button-back", N_("Button Back") },
76
{ BTN_TASK, "button-task", N_("Button Task") },
72
78
{ BTN_WHEEL, "button-wheel", N_("Button Wheel") },
82
88
static const LinuxInputEvent rel_events[] =
84
{ REL_WHEEL, "wheel-turn-left", N_("Wheel Turn Left") },
85
{ REL_WHEEL, "wheel-turn-right", N_("Wheel Turn Right") },
86
{ REL_DIAL, "dial-turn-left", N_("Dial Turn Left") },
87
{ REL_DIAL, "dial-turn-right", N_("Dial Turn Right") },
90
{ REL_X, "x-move-left", N_("X Move Left") },
91
{ REL_X, "x-move-right", N_("X Move Right") },
92
{ REL_Y, "y-move-away", N_("Y Move Away") },
93
{ REL_Y, "y-move-near", N_("Y Move Near") },
94
{ REL_Z, "z-move-up", N_("Z Move Up") },
95
{ REL_Z, "z-move-down", N_("Z Move Down") },
97
{ REL_RX, "x-axis-tilt-away", N_("X Axis Tilt Away") },
98
{ REL_RX, "x-axis-tilt-near", N_("X Axis Tilt Near") },
99
{ REL_RY, "y-axis-tilt-right", N_("Y Axis Tilt Right") },
100
{ REL_RY, "y-axis-tilt-left", N_("Y Axis Tilt Left") },
101
{ REL_RZ, "z-axis-turn-left", N_("Z Axis Turn Left") },
102
{ REL_RZ, "z-axis-turn-right", N_("Z Axis Turn Right") },
104
{ REL_HWHEEL, "horizontal-wheel-turn-back", N_("Horiz. Wheel Turn Back") },
105
{ REL_HWHEEL, "horizontal-wheel-turn-forward", N_("Horiz. Wheel Turn Forward") },
106
{ REL_DIAL, "dial-turn-left", N_("Dial Turn Left") },
107
{ REL_DIAL, "dial-turn-right", N_("Dial Turn Right") },
108
{ REL_WHEEL, "wheel-turn-left", N_("Wheel Turn Left") },
109
{ REL_WHEEL, "wheel-turn-right", N_("Wheel Turn Right") },
138
164
static const gchar * linux_input_get_event_blurb (GimpController *controller,
141
static gboolean linux_input_set_device (ControllerLinuxInput *controller,
142
const gchar *device);
143
static gboolean linux_input_read_event (GIOChannel *io,
167
static void linux_input_device_changed (ControllerLinuxInput *controller,
169
static gboolean linux_input_set_device (ControllerLinuxInput *controller,
170
const gchar *device);
171
static gboolean linux_input_read_event (GIOChannel *io,
148
176
static const GimpModuleInfo linux_input_info =
150
178
GIMP_MODULE_ABI_VERSION,
151
179
N_("Linux input event controller"),
152
"Sven Neumann <sven@gimp.org>",
154
"(c) 2004, released under the GPL",
180
"Sven Neumann <sven@gimp.org>, Michael Natterer <mitch@gimp.org>",
182
"(c) 2004-2007, released under the GPL",
220
250
_("The name of the device to read Linux Input events from."),
224
GIMP_MODULE_PARAM_SERIALIZE));
252
GIMP_CONFIG_PARAM_FLAGS));
254
g_object_class_install_property (object_class, PROP_DEVICE_STORE,
255
g_param_spec_object ("device-values",
257
GIMP_TYPE_INPUT_DEVICE_STORE,
226
261
controller_class->name = _("Linux Input");
227
262
controller_class->help_id = "gimp-controller-linux-input";
263
controller_class->stock_id = GIMP_STOCK_CONTROLLER_LINUX_INPUT;
229
265
controller_class->get_n_events = linux_input_get_n_events;
230
266
controller_class->get_event_name = linux_input_get_event_name;
401
#define BITS_PER_LONG (sizeof(long) * 8)
402
#define NBITS(x) ((((x)-1)/BITS_PER_LONG)+1)
403
#define OFF(x) ((x)%BITS_PER_LONG)
404
#define BIT(x) (1UL<<OFF(x))
405
#define LONG(x) ((x)/BITS_PER_LONG)
406
#define test_bit(bit, array) ((array[LONG(bit)] >> OFF(bit)) & 1)
409
linux_input_get_device_info (ControllerLinuxInput *controller,
412
unsigned long evbit[NBITS (EV_MAX)];
413
unsigned long keybit[NBITS (KEY_MAX)];
414
unsigned long relbit[NBITS (REL_MAX)];
415
unsigned long absbit[NBITS (ABS_MAX)];
418
gint num_ext_keys = 0;
419
gint num_buttons = 0;
423
/* get event type bits */
424
ioctl (fd, EVIOCGBIT (0, EV_MAX), evbit);
426
if (test_bit (EV_KEY, evbit))
430
/* get keyboard bits */
431
ioctl (fd, EVIOCGBIT (EV_KEY, KEY_MAX), keybit);
433
/** count typical keyboard keys only */
434
for (i = KEY_Q; i < KEY_M; i++)
435
if (test_bit (i, keybit))
439
g_print ("%s: key 0x%02x present\n", G_STRFUNC, i);
442
g_print ("%s: #keys = %d\n", G_STRFUNC, num_keys);
444
for (i = KEY_OK; i < KEY_MAX; i++)
445
if (test_bit (i, keybit))
449
g_print ("%s: ext key 0x%02x present\n", G_STRFUNC, i);
452
g_print ("%s: #ext_keys = %d\n", G_STRFUNC, num_ext_keys);
454
for (i = BTN_MISC; i < KEY_OK; i++)
455
if (test_bit (i, keybit))
459
g_print ("%s: button 0x%02x present\n", G_STRFUNC, i);
462
g_print ("%s: #buttons = %d\n", G_STRFUNC, num_buttons);
465
if (test_bit (EV_REL, evbit))
469
/* get bits for relative axes */
470
ioctl (fd, EVIOCGBIT (EV_REL, REL_MAX), relbit);
472
for (i = 0; i < REL_MAX; i++)
473
if (test_bit (i, relbit))
477
g_print ("%s: rel 0x%02x present\n", G_STRFUNC, i);
480
g_print ("%s: #rels = %d\n", G_STRFUNC, num_rels);
483
if (test_bit (EV_ABS, evbit))
487
/* get bits for absolute axes */
488
ioctl (fd, EVIOCGBIT (EV_ABS, ABS_MAX), absbit);
490
for (i = 0; i < ABS_MAX; i++)
491
if (test_bit (i, absbit))
493
struct input_absinfo absinfo;
497
/* get info for the absolute axis */
498
ioctl (fd, EVIOCGABS (i), &absinfo);
500
g_print ("%s: abs 0x%02x present [%d..%d]\n", G_STRFUNC, i,
501
absinfo.minimum, absinfo.maximum);
504
g_print ("%s: #abs = %d\n", G_STRFUNC, num_abs);
509
linux_input_device_changed (ControllerLinuxInput *controller,
512
if (controller->device && strcmp (udi, controller->device) == 0)
514
linux_input_set_device (controller, udi);
515
g_object_notify (G_OBJECT (controller), "device");
333
520
linux_input_set_device (ControllerLinuxInput *controller,
334
521
const gchar *device)
336
525
if (controller->io)
338
527
g_source_remove (controller->io_id);
368
572
g_object_set (controller, "name", name, NULL);
371
state = g_strdup_printf (_("Reading from %s"), controller->device);
575
linux_input_get_device_info (controller, fd);
577
state = g_strdup_printf (_("Reading from %s"), filename);
372
578
g_object_set (controller, "state", state, NULL);
375
583
controller->io = g_io_channel_unix_new (fd);
376
584
g_io_channel_set_close_on_unref (controller->io, TRUE);
377
585
g_io_channel_set_encoding (controller->io, NULL, NULL);
389
597
g_object_set (controller, "state", state, NULL);
603
else if (controller->store)
395
g_object_set (controller, "state", _("No device configured"), NULL);
605
GError *error = gimp_input_device_store_get_error (controller->store);
609
g_object_set (controller, "state", error->message, NULL);
610
g_error_free (error);
614
g_object_set (controller, "state", _("Device not available"), NULL);
451
670
if (n_bytes == sizeof (struct input_event))
672
GimpController *controller = GIMP_CONTROLLER (data);
673
GimpControllerEvent cevent = { 0, };
679
g_print ("%s: EV_KEY code = 0x%02x\n", G_STRFUNC, ev.code);
456
681
for (i = 0; i < G_N_ELEMENTS (key_events); i++)
457
682
if (ev.code == key_events[i].code)
459
GimpController *controller = GIMP_CONTROLLER (data);
460
GimpControllerEvent cevent;
462
684
cevent.any.type = GIMP_CONTROLLER_EVENT_TRIGGER;
463
cevent.any.source = GIMP_CONTROLLER (data);
685
cevent.any.source = controller;
464
686
cevent.any.event_id = i;
466
688
gimp_controller_event (controller, &cevent);
695
g_print ("%s: EV_REL code = 0x%02x (value = %d)\n", G_STRFUNC,
473
698
for (i = 0; i < G_N_ELEMENTS (rel_events); i++)
474
699
if (ev.code == rel_events[i].code)
476
GimpController *controller = GIMP_CONTROLLER (data);
477
GimpControllerEvent cevent;
480
cevent.any.type = GIMP_CONTROLLER_EVENT_TRIGGER;
701
cevent.any.type = GIMP_CONTROLLER_EVENT_VALUE;
481
702
cevent.any.source = controller;
482
703
cevent.any.event_id = G_N_ELEMENTS (key_events) + i;
484
for (count = ev.value; count < 0; count++)
485
gimp_controller_event (controller, &cevent);
487
cevent.any.event_id++;
489
for (count = ev.value; count > 0; count--)
490
gimp_controller_event (controller, &cevent);
705
g_value_init (&cevent.value.value, G_TYPE_DOUBLE);
709
g_value_set_double (&cevent.value.value, -ev.value);
713
cevent.any.event_id++;
715
g_value_set_double (&cevent.value.value, ev.value);
718
gimp_controller_event (controller, &cevent);
720
g_value_unset (&cevent.value.value);
727
g_print ("%s: EV_ABS code = 0x%02x (value = %d)\n", G_STRFUNC,