~ubuntu-branches/ubuntu/jaunty/gimp/jaunty-security

« back to all changes in this revision

Viewing changes to modules/controller_linux_input.c

  • Committer: Bazaar Package Importer
  • Author(s): Daniel Holbach
  • Date: 2007-05-02 16:33:03 UTC
  • mfrom: (1.1.4 upstream)
  • Revision ID: james.westby@ubuntu.com-20070502163303-bvzhjzbpw8qglc4y
Tags: 2.3.16-1ubuntu1
* Resynchronized with Debian, remaining Ubuntu changes:
  - debian/rules: i18n magic.
* debian/control.in:
  - Maintainer: Ubuntu Core Developers <ubuntu-devel@lists.ubuntu.com>
* debian/patches/02_help-message.patch,
  debian/patches/03_gimp.desktop.in.in.patch,
  debian/patches/10_dont_show_wizard.patch: updated.
* debian/patches/04_composite-signedness.patch,
  debian/patches/05_add-letter-spacing.patch: dropped, used upstream.

Show diffs side-by-side

added added

removed removed

Lines of Context:
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
3
3
 *
4
4
 * controller_linux_input.c
5
 
 * Copyright (C) 2004 Sven Neumann <sven@gimp.org>
6
 
 *
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.
11
 
 *
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>
 
7
 *
 
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.
 
12
 *
 
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.
16
17
 *
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.
21
21
 */
22
22
 
23
23
#include "config.h"
30
30
 
31
31
#include <linux/input.h>
32
32
 
 
33
#include <glib/gstdio.h>
 
34
 
33
35
#include <gtk/gtk.h>
34
36
 
 
37
#include "libgimpconfig/gimpconfig.h"
35
38
#include "libgimpmodule/gimpmodule.h"
36
39
#include "libgimpwidgets/gimpwidgets.h"
37
40
 
38
41
#define GIMP_ENABLE_CONTROLLER_UNDER_CONSTRUCTION
39
42
#include "libgimpwidgets/gimpcontroller.h"
40
43
 
 
44
#include "gimpinputdevicestore.h"
 
45
 
41
46
#include "libgimp/libgimp-intl.h"
42
47
 
43
48
 
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")      },
71
77
#ifdef BTN_WHEEL
72
78
  { BTN_WHEEL,     "button-wheel",     N_("Button Wheel")     },
73
79
#endif
81
87
 
82
88
static const LinuxInputEvent rel_events[] =
83
89
{
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")               },
 
96
#ifdef REL_RX
 
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")         },
 
103
#endif  /* REL_RX */
 
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")          },
88
110
};
89
111
 
90
112
 
91
113
enum
92
114
{
93
115
  PROP_0,
94
 
  PROP_DEVICE
 
116
  PROP_DEVICE,
 
117
  PROP_DEVICE_STORE
95
118
};
96
119
 
97
120
 
107
130
 
108
131
struct _ControllerLinuxInput
109
132
{
110
 
  GimpController  parent_instance;
 
133
  GimpController        parent_instance;
111
134
 
112
 
  gchar          *device;
113
 
  GIOChannel     *io;
114
 
  guint           io_id;
 
135
  GimpInputDeviceStore *store;
 
136
  gchar                *device;
 
137
  GIOChannel           *io;
 
138
  guint                 io_id;
115
139
};
116
140
 
117
141
struct _ControllerLinuxInputClass
122
146
 
123
147
GType         linux_input_get_type     (GTypeModule    *module);
124
148
static void   linux_input_class_init   (ControllerLinuxInputClass *klass);
 
149
static void   linux_input_init         (ControllerLinuxInput      *controller);
125
150
static void   linux_input_dispose      (GObject        *object);
 
151
static void   linux_input_finalize     (GObject        *object);
126
152
static void   linux_input_set_property (GObject        *object,
127
153
                                        guint           property_id,
128
154
                                        const GValue   *value,
138
164
static const gchar * linux_input_get_event_blurb  (GimpController *controller,
139
165
                                                   gint            event_id);
140
166
 
141
 
static gboolean      linux_input_set_device (ControllerLinuxInput *controller,
142
 
                                             const gchar          *device);
143
 
static gboolean      linux_input_read_event (GIOChannel           *io,
144
 
                                             GIOCondition          cond,
145
 
                                             gpointer              data);
 
167
static void          linux_input_device_changed   (ControllerLinuxInput *controller,
 
168
                                                   const gchar          *udi);
 
169
static gboolean      linux_input_set_device       (ControllerLinuxInput *controller,
 
170
                                                   const gchar          *device);
 
171
static gboolean      linux_input_read_event       (GIOChannel           *io,
 
172
                                                   GIOCondition          cond,
 
173
                                                   gpointer              data);
146
174
 
147
175
 
148
176
static const GimpModuleInfo linux_input_info =
149
177
{
150
178
  GIMP_MODULE_ABI_VERSION,
151
179
  N_("Linux input event controller"),
152
 
  "Sven Neumann <sven@gimp.org>",
153
 
  "v0.1",
154
 
  "(c) 2004, released under the GPL",
155
 
  "June 2004"
 
180
  "Sven Neumann <sven@gimp.org>, Michael Natterer <mitch@gimp.org>",
 
181
  "v0.2",
 
182
  "(c) 2004-2007, released under the GPL",
 
183
  "2004-2007"
156
184
};
157
185
 
158
186
 
169
197
G_MODULE_EXPORT gboolean
170
198
gimp_module_register (GTypeModule *module)
171
199
{
 
200
  gimp_input_device_store_get_type (module);
172
201
  linux_input_get_type (module);
173
202
 
174
203
  return TRUE;
180
209
{
181
210
  if (! controller_type)
182
211
    {
183
 
      static const GTypeInfo controller_info =
 
212
      const GTypeInfo controller_info =
184
213
      {
185
214
        sizeof (ControllerLinuxInputClass),
186
215
        (GBaseInitFunc) NULL,
190
219
        NULL,           /* class_data     */
191
220
        sizeof (ControllerLinuxInput),
192
221
        0,              /* n_preallocs    */
193
 
        NULL            /* instance_init  */
 
222
        (GInstanceInitFunc) linux_input_init
194
223
      };
195
224
 
196
225
      controller_type = g_type_module_register_type (module,
211
240
  parent_class = g_type_class_peek_parent (klass);
212
241
 
213
242
  object_class->dispose            = linux_input_dispose;
 
243
  object_class->finalize           = linux_input_finalize;
214
244
  object_class->get_property       = linux_input_get_property;
215
245
  object_class->set_property       = linux_input_set_property;
216
246
 
219
249
                                                        _("Device:"),
220
250
                                                        _("The name of the device to read Linux Input events from."),
221
251
                                                        NULL,
222
 
                                                        G_PARAM_READWRITE |
223
 
                                                        G_PARAM_CONSTRUCT |
224
 
                                                        GIMP_MODULE_PARAM_SERIALIZE));
 
252
                                                        GIMP_CONFIG_PARAM_FLAGS));
 
253
#ifdef HAVE_LIBHAL
 
254
  g_object_class_install_property (object_class, PROP_DEVICE_STORE,
 
255
                                   g_param_spec_object ("device-values",
 
256
                                                        NULL, NULL,
 
257
                                                        GIMP_TYPE_INPUT_DEVICE_STORE,
 
258
                                                        G_PARAM_READABLE));
 
259
#endif
225
260
 
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;
228
264
 
229
265
  controller_class->get_n_events    = linux_input_get_n_events;
230
266
  controller_class->get_event_name  = linux_input_get_event_name;
232
268
}
233
269
 
234
270
static void
 
271
linux_input_init (ControllerLinuxInput *controller)
 
272
{
 
273
  controller->store = gimp_input_device_store_new ();
 
274
 
 
275
  if (controller->store)
 
276
    {
 
277
      g_signal_connect_swapped (controller->store, "device-added",
 
278
                                G_CALLBACK (linux_input_device_changed),
 
279
                                controller);
 
280
      g_signal_connect_swapped (controller->store, "device-removed",
 
281
                                G_CALLBACK (linux_input_device_changed),
 
282
                                controller);
 
283
    }
 
284
}
 
285
 
 
286
static void
235
287
linux_input_dispose (GObject *object)
236
288
{
237
289
  ControllerLinuxInput *controller = CONTROLLER_LINUX_INPUT (object);
242
294
}
243
295
 
244
296
static void
 
297
linux_input_finalize (GObject *object)
 
298
{
 
299
  ControllerLinuxInput *controller = CONTROLLER_LINUX_INPUT (object);
 
300
 
 
301
  if (controller->store)
 
302
    {
 
303
      g_object_unref (controller->store);
 
304
      controller->store = NULL;
 
305
    }
 
306
 
 
307
  G_OBJECT_CLASS (parent_class)->finalize (object);
 
308
}
 
309
 
 
310
static void
245
311
linux_input_set_property (GObject      *object,
246
312
                          guint         property_id,
247
313
                          const GValue *value,
273
339
    case PROP_DEVICE:
274
340
      g_value_set_string (value, controller->device);
275
341
      break;
 
342
    case PROP_DEVICE_STORE:
 
343
      g_value_set_object (value, controller->store);
 
344
      break;
276
345
    default:
277
346
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
278
347
      break;
329
398
    }
330
399
}
331
400
 
 
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)
 
407
 
 
408
static void
 
409
linux_input_get_device_info (ControllerLinuxInput *controller,
 
410
                             int                   fd)
 
411
{
 
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)];
 
416
 
 
417
  gint num_keys     = 0;
 
418
  gint num_ext_keys = 0;
 
419
  gint num_buttons  = 0;
 
420
  gint num_rels     = 0;
 
421
  gint num_abs      = 0;
 
422
 
 
423
  /* get event type bits */
 
424
  ioctl (fd, EVIOCGBIT (0, EV_MAX), evbit);
 
425
 
 
426
  if (test_bit (EV_KEY, evbit))
 
427
    {
 
428
      gint i;
 
429
 
 
430
      /* get keyboard bits */
 
431
      ioctl (fd, EVIOCGBIT (EV_KEY, KEY_MAX), keybit);
 
432
 
 
433
      /**  count typical keyboard keys only */
 
434
      for (i = KEY_Q; i < KEY_M; i++)
 
435
        if (test_bit (i, keybit))
 
436
          {
 
437
            num_keys++;
 
438
 
 
439
            g_print ("%s: key 0x%02x present\n", G_STRFUNC, i);
 
440
          }
 
441
 
 
442
      g_print ("%s: #keys = %d\n", G_STRFUNC, num_keys);
 
443
 
 
444
      for (i = KEY_OK; i < KEY_MAX; i++)
 
445
        if (test_bit (i, keybit))
 
446
          {
 
447
            num_ext_keys++;
 
448
 
 
449
            g_print ("%s: ext key 0x%02x present\n", G_STRFUNC, i);
 
450
          }
 
451
 
 
452
      g_print ("%s: #ext_keys = %d\n", G_STRFUNC, num_ext_keys);
 
453
 
 
454
      for (i = BTN_MISC; i < KEY_OK; i++)
 
455
        if (test_bit (i, keybit))
 
456
          {
 
457
            num_buttons++;
 
458
 
 
459
            g_print ("%s: button 0x%02x present\n", G_STRFUNC, i);
 
460
          }
 
461
 
 
462
      g_print ("%s: #buttons = %d\n", G_STRFUNC, num_buttons);
 
463
    }
 
464
 
 
465
  if (test_bit (EV_REL, evbit))
 
466
    {
 
467
      gint i;
 
468
 
 
469
      /* get bits for relative axes */
 
470
      ioctl (fd, EVIOCGBIT (EV_REL, REL_MAX), relbit);
 
471
 
 
472
      for (i = 0; i < REL_MAX; i++)
 
473
        if (test_bit (i, relbit))
 
474
          {
 
475
            num_rels++;
 
476
 
 
477
            g_print ("%s: rel 0x%02x present\n", G_STRFUNC, i);
 
478
          }
 
479
 
 
480
      g_print ("%s: #rels = %d\n", G_STRFUNC, num_rels);
 
481
    }
 
482
 
 
483
  if (test_bit (EV_ABS, evbit))
 
484
    {
 
485
      gint i;
 
486
 
 
487
      /* get bits for absolute axes */
 
488
      ioctl (fd, EVIOCGBIT (EV_ABS, ABS_MAX), absbit);
 
489
 
 
490
      for (i = 0; i < ABS_MAX; i++)
 
491
        if (test_bit (i, absbit))
 
492
          {
 
493
            struct input_absinfo absinfo;
 
494
 
 
495
            num_abs++;
 
496
 
 
497
            /* get info for the absolute axis */
 
498
            ioctl (fd, EVIOCGABS (i), &absinfo);
 
499
 
 
500
            g_print ("%s: abs 0x%02x present [%d..%d]\n", G_STRFUNC, i,
 
501
                     absinfo.minimum, absinfo.maximum);
 
502
          }
 
503
 
 
504
      g_print ("%s: #abs = %d\n", G_STRFUNC, num_abs);
 
505
    }
 
506
}
 
507
 
 
508
static void
 
509
linux_input_device_changed (ControllerLinuxInput *controller,
 
510
                            const gchar          *udi)
 
511
{
 
512
  if (controller->device && strcmp (udi, controller->device) == 0)
 
513
    {
 
514
      linux_input_set_device (controller, udi);
 
515
      g_object_notify (G_OBJECT (controller), "device");
 
516
    }
 
517
}
 
518
 
332
519
static gboolean
333
520
linux_input_set_device (ControllerLinuxInput *controller,
334
521
                        const gchar          *device)
335
522
{
 
523
  gchar *filename;
 
524
 
336
525
  if (controller->io)
337
526
    {
338
527
      g_source_remove (controller->io_id);
351
540
 
352
541
  if (controller->device && strlen (controller->device))
353
542
    {
 
543
      if (controller->store)
 
544
        filename = gimp_input_device_store_get_device_file (controller->store,
 
545
                                                            controller->device);
 
546
      else
 
547
        filename = g_strdup (controller->device);
 
548
    }
 
549
  else
 
550
    {
 
551
      g_object_set (controller, "state", _("No device configured"), NULL);
 
552
 
 
553
      return FALSE;
 
554
    }
 
555
 
 
556
  if (filename)
 
557
    {
354
558
      gchar *state;
355
559
      gint   fd;
356
560
 
357
 
      fd = open (controller->device, O_RDONLY);
 
561
      fd = g_open (filename, O_RDONLY, 0);
358
562
 
359
563
      if (fd >= 0)
360
564
        {
368
572
              g_object_set (controller, "name", name, NULL);
369
573
            }
370
574
 
371
 
          state = g_strdup_printf (_("Reading from %s"), controller->device);
 
575
          linux_input_get_device_info (controller, fd);
 
576
 
 
577
          state = g_strdup_printf (_("Reading from %s"), filename);
372
578
          g_object_set (controller, "state", state, NULL);
373
579
          g_free (state);
374
580
 
 
581
          g_free (filename);
 
582
 
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);
390
598
          g_free (state);
391
599
        }
 
600
 
 
601
      g_free (filename);
392
602
    }
393
 
  else
 
603
  else if (controller->store)
394
604
    {
395
 
      g_object_set (controller, "state", _("No device configured"), NULL);
 
605
      GError *error = gimp_input_device_store_get_error (controller->store);
 
606
 
 
607
      if (error)
 
608
        {
 
609
          g_object_set (controller, "state", error->message, NULL);
 
610
          g_error_free (error);
 
611
        }
 
612
      else
 
613
        {
 
614
          g_object_set (controller, "state", _("Device not available"), NULL);
 
615
        }
396
616
    }
397
617
 
398
618
  return FALSE;
408
628
  GError               *error = NULL;
409
629
  struct input_event    ev;
410
630
  gsize                 n_bytes;
411
 
  gint                  i;
412
631
 
413
632
  status = g_io_channel_read_chars (io,
414
633
                                    (gchar *) &ev,
450
669
 
451
670
  if (n_bytes == sizeof (struct input_event))
452
671
    {
 
672
      GimpController      *controller = GIMP_CONTROLLER (data);
 
673
      GimpControllerEvent  cevent     = { 0, };
 
674
      gint                 i;
 
675
 
453
676
      switch (ev.type)
454
677
        {
455
678
        case EV_KEY:
 
679
          g_print ("%s: EV_KEY code = 0x%02x\n", G_STRFUNC, ev.code);
 
680
 
456
681
          for (i = 0; i < G_N_ELEMENTS (key_events); i++)
457
682
            if (ev.code == key_events[i].code)
458
683
              {
459
 
                GimpController      *controller = GIMP_CONTROLLER (data);
460
 
                GimpControllerEvent  cevent;
461
 
 
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;
465
687
 
466
688
                gimp_controller_event (controller, &cevent);
470
692
          break;
471
693
 
472
694
        case EV_REL:
 
695
          g_print ("%s: EV_REL code = 0x%02x (value = %d)\n", G_STRFUNC,
 
696
                   ev.code, ev.value);
 
697
 
473
698
          for (i = 0; i < G_N_ELEMENTS (rel_events); i++)
474
699
            if (ev.code == rel_events[i].code)
475
700
              {
476
 
                GimpController      *controller = GIMP_CONTROLLER (data);
477
 
                GimpControllerEvent  cevent;
478
 
                gint                 count;
479
 
 
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;
483
704
 
484
 
                for (count = ev.value; count < 0; count++)
485
 
                  gimp_controller_event (controller, &cevent);
486
 
 
487
 
                cevent.any.event_id++;
488
 
 
489
 
                for (count = ev.value; count > 0; count--)
490
 
                  gimp_controller_event (controller, &cevent);
491
 
 
492
 
                break;
 
705
                g_value_init (&cevent.value.value, G_TYPE_DOUBLE);
 
706
 
 
707
                if (ev.value < 0)
 
708
                  {
 
709
                    g_value_set_double (&cevent.value.value, -ev.value);
 
710
                  }
 
711
                else
 
712
                  {
 
713
                    cevent.any.event_id++;
 
714
 
 
715
                    g_value_set_double (&cevent.value.value, ev.value);
 
716
                  }
 
717
 
 
718
                gimp_controller_event (controller, &cevent);
 
719
 
 
720
                g_value_unset (&cevent.value.value);
 
721
 
 
722
               break;
493
723
              }
494
724
          break;
495
725
 
 
726
        case EV_ABS:
 
727
          g_print ("%s: EV_ABS code = 0x%02x (value = %d)\n", G_STRFUNC,
 
728
                   ev.code, ev.value);
 
729
          break;
 
730
 
496
731
        default:
497
732
          break;
498
733
        }