~oem-solutions-group/unity-2d/clutter-1.0

« back to all changes in this revision

Viewing changes to clutter/x11/clutter-event-x11.c

  • Committer: Bazaar Package Importer
  • Author(s): Emilio Pozuelo Monfort
  • Date: 2010-03-21 13:27:56 UTC
  • mto: (2.1.3 experimental)
  • mto: This revision was merged to the branch mainline in revision 8.
  • Revision ID: james.westby@ubuntu.com-20100321132756-nf8yd30yxo3zzwcm
Tags: upstream-1.2.2
ImportĀ upstreamĀ versionĀ 1.2.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/* Clutter.
2
2
 * An OpenGL based 'interactive canvas' library.
3
 
 * Authored By Matthew Allum  <mallum@openedhand.com>
4
 
 * Copyright (C) 2006-2007 OpenedHand
 
3
 *
 
4
 * Copyright (C) 2006, 2007, 2008  OpenedHand Ltd
 
5
 * Copyright (C) 2009, 2010  Intel Corp.
5
6
 *
6
7
 * This library is free software; you can redistribute it and/or
7
8
 * modify it under the terms of the GNU Lesser General Public
14
15
 * Lesser General Public License for more details.
15
16
 *
16
17
 * You should have received a copy of the GNU Lesser General Public
17
 
 * License along with this library; if not, write to the
18
 
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19
 
 * Boston, MA 02111-1307, USA.
 
18
 * License along with this library. If not, see <http://www.gnu.org/licenses/>.
 
19
 *
 
20
 *
 
21
 *
 
22
 * Authored by:
 
23
 *      Matthew Allum <mallum@openedhand.com>
 
24
 *      Emmanuele Bassi <ebassi@linux.intel.com>
20
25
 */
21
26
 
22
27
#ifdef HAVE_CONFIG_H
183
188
  g_source_add_poll (source, &event_source->event_poll_fd);
184
189
  g_source_set_can_recurse (source, TRUE);
185
190
  g_source_attach (source, NULL);
186
 
 
187
191
}
188
192
 
189
193
void
263
267
    }
264
268
}
265
269
 
266
 
#if 0 /* See XInput keyboard comment below HAVE_XINPUT */
 
270
#ifdef HAVE_XINPUT
267
271
static void
268
 
convert_xdevicekey_to_xkey (XDeviceKeyEvent *xkev, XEvent *xevent)
 
272
convert_xdevicekey_to_xkey (XDeviceKeyEvent *xkev,
 
273
                            XEvent          *xevent)
269
274
{
270
275
  xevent->xany.type = xevent->xkey.type = xkev->type;
271
276
  xevent->xkey.serial = xkev->serial;
410
415
                 ClutterEvent   *event,
411
416
                 XEvent         *xevent)
412
417
{
413
 
  ClutterBackendX11  *backend_x11;
414
 
  ClutterStageX11    *stage_x11;
415
 
  ClutterStage       *stage;
 
418
  ClutterBackendX11 *backend_x11;
 
419
  ClutterStageX11 *stage_x11;
 
420
  ClutterStage *stage;
416
421
  ClutterStageWindow *impl;
417
 
  gboolean            res, not_yet_handled = FALSE;
418
 
  Window              xwindow, stage_xwindow;
 
422
  ClutterDeviceManager *manager;
 
423
  gboolean res, not_yet_handled = FALSE;
 
424
  Window xwindow, stage_xwindow;
 
425
  ClutterInputDevice *device;
419
426
 
420
 
  backend_x11    = CLUTTER_BACKEND_X11 (backend);
 
427
  backend_x11 = CLUTTER_BACKEND_X11 (backend);
421
428
 
422
429
  xwindow = xevent->xany.window;
423
430
 
424
431
  if (backend_x11->event_filters)
425
432
    {
426
 
      GSList                *node;
427
 
      ClutterX11EventFilter *filter;
 
433
      GSList *node;
428
434
 
429
435
      node = backend_x11->event_filters;
430
436
 
431
437
      while (node)
432
438
        {
433
 
          filter = node->data;
 
439
          ClutterX11EventFilter *filter = node->data;
434
440
 
435
441
          switch (filter->func (xevent, event, filter->data))
436
442
            {
448
454
        }
449
455
    }
450
456
 
451
 
  /*
452
 
   * Do further processing only on events for the stage window
453
 
   * (the x11 filters might be getting events for other windows, so do not
454
 
   * mess them about.
 
457
  /* Do further processing only on events for the stage window (the x11
 
458
   * filters might be getting events for other windows, so do not mess
 
459
   * them about.
455
460
   */
456
461
  stage = clutter_x11_get_stage_from_window (xwindow);
457
 
 
458
462
  if (stage == NULL)
459
 
      return FALSE;
 
463
    return FALSE;
460
464
 
461
 
  impl           = _clutter_stage_get_window (stage);
462
 
  stage_x11      = CLUTTER_STAGE_X11 (impl);
463
 
  stage_xwindow  = xwindow; /* clutter_x11_get_stage_window (stage); */
 
465
  impl = _clutter_stage_get_window (stage);
 
466
  stage_x11 = CLUTTER_STAGE_X11 (impl);
 
467
  stage_xwindow = xwindow; /* clutter_x11_get_stage_window (stage); */
464
468
 
465
469
  event->any.stage = stage;
466
470
 
468
472
 
469
473
  update_last_event_time (backend_x11, xevent);
470
474
 
 
475
  manager = clutter_device_manager_get_default ();
 
476
 
471
477
  switch (xevent->type)
472
478
    {
473
479
    case ConfigureNotify:
479
485
                        xevent->xconfigure.width,
480
486
                        xevent->xconfigure.height);
481
487
 
482
 
          stage_x11->xwin_width = xevent->xconfigure.width;
483
 
          stage_x11->xwin_height = xevent->xconfigure.height;
 
488
          /* Queue a relayout - we want glViewport to be called
 
489
           * with the correct values, and this is done in ClutterStage
 
490
           * via _cogl_onscreen_clutter_backend_set_size ().
 
491
           *
 
492
           * We queue a relayout, because if this ConfigureNotify is
 
493
           * in response to a size we set in the application, the
 
494
           * set_size above is essentially a null-op.
 
495
           *
 
496
           * Make sure we do this only when the size has changed,
 
497
           * otherwise we end up relayouting on window moves.
 
498
           */
 
499
          if ((stage_x11->state & CLUTTER_STAGE_STATE_FULLSCREEN) ||
 
500
              (stage_x11->xwin_width != xevent->xconfigure.width) ||
 
501
              (stage_x11->xwin_height != xevent->xconfigure.height))
 
502
          clutter_actor_queue_relayout (CLUTTER_ACTOR (stage));
 
503
 
 
504
          /* If we're fullscreened, we want these variables to
 
505
           * represent the size of the window before it was set
 
506
           * to fullscreen.
 
507
           */
 
508
          if (!(stage_x11->state & CLUTTER_STAGE_STATE_FULLSCREEN))
 
509
            {
 
510
              stage_x11->xwin_width = xevent->xconfigure.width;
 
511
              stage_x11->xwin_height = xevent->xconfigure.height;
 
512
            }
 
513
 
 
514
          clutter_actor_set_size (CLUTTER_ACTOR (stage),
 
515
                                  xevent->xconfigure.width,
 
516
                                  xevent->xconfigure.height);
484
517
 
485
518
          CLUTTER_UNSET_PRIVATE_FLAGS (stage_x11->wrapper,
486
519
                                       CLUTTER_STAGE_IN_RESIZE);
489
522
           * to set up the GL viewport with the new size
490
523
           */
491
524
          clutter_stage_ensure_viewport (stage);
492
 
 
493
 
          clutter_actor_queue_relayout (CLUTTER_ACTOR (stage_x11->wrapper));
494
525
        }
495
526
      res = FALSE;
496
527
      break;
537
568
                  else
538
569
                    stage_x11->state &= ~CLUTTER_STAGE_STATE_FULLSCREEN;
539
570
 
 
571
                  stage_x11->fullscreening = fullscreen_set;
 
572
 
540
573
                  event->type = CLUTTER_STAGE_STATE;
541
574
                  event->stage_state.changed_mask =
542
575
                    CLUTTER_STAGE_STATE_FULLSCREEN;
622
655
 
623
656
    case KeyPress:
624
657
      event->key.type = event->type = CLUTTER_KEY_PRESS;
 
658
      event->key.device =
 
659
        clutter_device_manager_get_core_device (manager,
 
660
                                                CLUTTER_POINTER_DEVICE);
 
661
 
625
662
      translate_key_event (backend, event, xevent);
626
663
 
627
664
      set_user_time (backend_x11, &xwindow, xevent->xkey.time);
628
665
      break;
629
666
              
630
667
    case KeyRelease:
 
668
      /* old-style X11 terminals require that even modern X11 send
 
669
       * KeyPress/KeyRelease pairs when auto-repeating. for this
 
670
       * reason modern(-ish) API like XKB has a way to detect
 
671
       * auto-repeat and do a single KeyRelease at the end of a
 
672
       * KeyPress sequence.
 
673
       *
 
674
       * this check emulates XKB's detectable auto-repeat; we peek
 
675
       * the next event and check if it's a KeyPress for the same key
 
676
       * and timestamp - and then ignore it if it matches the
 
677
       * KeyRelease
 
678
       */
 
679
      if (XPending (xevent->xkey.display))
 
680
        {
 
681
          XEvent next_event;
 
682
 
 
683
          XPeekEvent (xevent->xkey.display, &next_event);
 
684
 
 
685
          if (next_event.type == KeyPress &&
 
686
              next_event.xkey.keycode == xevent->xkey.keycode &&
 
687
              next_event.xkey.time == xevent->xkey.time)
 
688
            {
 
689
              res = FALSE;
 
690
              break;
 
691
            }
 
692
        }
 
693
 
631
694
      event->key.type = event->type = CLUTTER_KEY_RELEASE;
 
695
      event->key.device =
 
696
        clutter_device_manager_get_core_device (manager,
 
697
                                                CLUTTER_KEYBOARD_DEVICE);
 
698
 
632
699
      translate_key_event (backend, event, xevent);
633
700
      break;
634
701
 
641
708
  /* Input device event handling.. */
642
709
  if (not_yet_handled)
643
710
    {
644
 
      if (!clutter_x11_has_xinput ())
 
711
      device = clutter_device_manager_get_core_device (manager,
 
712
                                                       CLUTTER_POINTER_DEVICE);
 
713
 
 
714
      /* Regular X event */
 
715
      switch (xevent->type)
645
716
        {
646
 
          /* Regular X event */
647
 
          switch (xevent->type)
 
717
        case ButtonPress:
 
718
          switch (xevent->xbutton.button)
648
719
            {
649
 
                        /* KeyPress / KeyRelease should reside here if XInput
650
 
             * worked properly
651
 
             */
652
 
            case ButtonPress:
653
 
              switch (xevent->xbutton.button)
654
 
                {
655
 
                case 4: /* up */
656
 
                case 5: /* down */
657
 
                case 6: /* left */
658
 
                case 7: /* right */
659
 
                  event->scroll.type = event->type = CLUTTER_SCROLL;
660
 
                  
661
 
                  if (xevent->xbutton.button == 4)
662
 
                    event->scroll.direction = CLUTTER_SCROLL_UP;
663
 
                  else if (xevent->xbutton.button == 5)
664
 
                    event->scroll.direction = CLUTTER_SCROLL_DOWN;
665
 
                  else if (xevent->xbutton.button == 6)
666
 
                    event->scroll.direction = CLUTTER_SCROLL_LEFT;
667
 
                  else
668
 
                    event->scroll.direction = CLUTTER_SCROLL_RIGHT;
669
 
                  
670
 
                  event->scroll.time = xevent->xbutton.time;
671
 
                  event->scroll.x = xevent->xbutton.x;
672
 
                  event->scroll.y = xevent->xbutton.y;
673
 
                  event->scroll.modifier_state = xevent->xbutton.state;
674
 
                  
675
 
                  break;
676
 
                default:
677
 
                  event->button.type = event->type = CLUTTER_BUTTON_PRESS;
678
 
                  event->button.time = xevent->xbutton.time;
679
 
                  event->button.x = xevent->xbutton.x;
680
 
                  event->button.y = xevent->xbutton.y;
681
 
                  event->button.modifier_state = xevent->xbutton.state;
682
 
                  event->button.button = xevent->xbutton.button;
683
 
                  
684
 
                  break;
685
 
                }
686
 
              
687
 
              set_user_time (backend_x11, &xwindow, event->button.time);
 
720
            case 4: /* up */
 
721
            case 5: /* down */
 
722
            case 6: /* left */
 
723
            case 7: /* right */
 
724
              event->scroll.type = event->type = CLUTTER_SCROLL;
 
725
 
 
726
              if (xevent->xbutton.button == 4)
 
727
                event->scroll.direction = CLUTTER_SCROLL_UP;
 
728
              else if (xevent->xbutton.button == 5)
 
729
                event->scroll.direction = CLUTTER_SCROLL_DOWN;
 
730
              else if (xevent->xbutton.button == 6)
 
731
                event->scroll.direction = CLUTTER_SCROLL_LEFT;
 
732
              else
 
733
                event->scroll.direction = CLUTTER_SCROLL_RIGHT;
 
734
 
 
735
              event->scroll.time = xevent->xbutton.time;
 
736
              event->scroll.x = xevent->xbutton.x;
 
737
              event->scroll.y = xevent->xbutton.y;
 
738
              event->scroll.modifier_state = xevent->xbutton.state;
 
739
              event->scroll.device = device;
688
740
              break;
689
 
              
690
 
            case ButtonRelease:
691
 
              /* scroll events don't have a corresponding release */
692
 
              if (xevent->xbutton.button == 4 ||
693
 
                  xevent->xbutton.button == 5 ||
694
 
                  xevent->xbutton.button == 6 ||
695
 
                  xevent->xbutton.button == 7)
696
 
                {
697
 
                  res = FALSE;
698
 
                  break;
699
 
                }
700
 
              
701
 
              event->button.type = event->type = CLUTTER_BUTTON_RELEASE;
 
741
 
 
742
            default:
 
743
              event->button.type = event->type = CLUTTER_BUTTON_PRESS;
702
744
              event->button.time = xevent->xbutton.time;
703
745
              event->button.x = xevent->xbutton.x;
704
746
              event->button.y = xevent->xbutton.y;
705
747
              event->button.modifier_state = xevent->xbutton.state;
706
748
              event->button.button = xevent->xbutton.button;
707
 
              break;
708
 
              
709
 
            case MotionNotify:
710
 
              event->motion.type = event->type = CLUTTER_MOTION;
711
 
              event->motion.time = xevent->xmotion.time;
712
 
              event->motion.x = xevent->xmotion.x;
713
 
              event->motion.y = xevent->xmotion.y;
714
 
              event->motion.modifier_state = xevent->xmotion.state;
715
 
              break;
716
 
 
717
 
            case EnterNotify:
718
 
              /* Convert enter notifies to motion events because X
719
 
                 doesn't emit the corresponding motion notify */
720
 
              event->motion.type = event->type = CLUTTER_MOTION;
721
 
              event->motion.time = xevent->xcrossing.time;
722
 
              event->motion.x = xevent->xcrossing.x;
723
 
              event->motion.y = xevent->xcrossing.y;
724
 
              event->motion.modifier_state = xevent->xcrossing.state;
725
 
              break;
726
 
 
727
 
            case LeaveNotify:
728
 
              event->crossing.type = event->type = CLUTTER_LEAVE;
729
 
              event->crossing.time = xevent->xcrossing.time;
730
 
              event->crossing.x = xevent->xcrossing.x;
731
 
              event->crossing.y = xevent->xcrossing.y;
732
 
              break;
733
 
 
734
 
            default:
735
 
              /* ignore every other event */
736
 
              res = FALSE;
737
 
              break;
738
 
            }
 
749
              event->button.device = device;
 
750
              break;
 
751
            }
 
752
 
 
753
          set_user_time (backend_x11, &xwindow, event->button.time);
 
754
 
 
755
          res = TRUE;
 
756
          break;
 
757
 
 
758
        case ButtonRelease:
 
759
          /* scroll events don't have a corresponding release */
 
760
          if (xevent->xbutton.button == 4 ||
 
761
              xevent->xbutton.button == 5 ||
 
762
              xevent->xbutton.button == 6 ||
 
763
              xevent->xbutton.button == 7)
 
764
            {
 
765
              res = FALSE;
 
766
              goto out;
 
767
            }
 
768
 
 
769
          event->button.type = event->type = CLUTTER_BUTTON_RELEASE;
 
770
          event->button.time = xevent->xbutton.time;
 
771
          event->button.x = xevent->xbutton.x;
 
772
          event->button.y = xevent->xbutton.y;
 
773
          event->button.modifier_state = xevent->xbutton.state;
 
774
          event->button.button = xevent->xbutton.button;
 
775
          event->button.device = device;
 
776
 
 
777
          res = TRUE;
 
778
          break;
 
779
 
 
780
        case MotionNotify:
 
781
          event->motion.type = event->type = CLUTTER_MOTION;
 
782
          event->motion.time = xevent->xmotion.time;
 
783
          event->motion.x = xevent->xmotion.x;
 
784
          event->motion.y = xevent->xmotion.y;
 
785
          event->motion.modifier_state = xevent->xmotion.state;
 
786
          event->motion.device = device;
 
787
 
 
788
          res = TRUE;
 
789
          break;
 
790
 
 
791
        case EnterNotify:
 
792
          /* we know that we are entering the stage here */
 
793
          _clutter_input_device_set_stage (device, stage);
 
794
          CLUTTER_NOTE (EVENT, "Entering the stage");
 
795
 
 
796
          /* Convert enter notifies to motion events because X
 
797
             doesn't emit the corresponding motion notify */
 
798
          event->motion.type = event->type = CLUTTER_MOTION;
 
799
          event->motion.time = xevent->xcrossing.time;
 
800
          event->motion.x = xevent->xcrossing.x;
 
801
          event->motion.y = xevent->xcrossing.y;
 
802
          event->motion.modifier_state = xevent->xcrossing.state;
 
803
          event->motion.source = CLUTTER_ACTOR (stage);
 
804
          event->motion.device = device;
 
805
 
 
806
          res = TRUE;
 
807
          break;
 
808
 
 
809
        case LeaveNotify:
 
810
          if (device->stage == NULL)
 
811
            {
 
812
              CLUTTER_NOTE (EVENT,
 
813
                            "Discarding LeaveNotify for ButtonRelease "
 
814
                            "event off-stage");
 
815
              res = FALSE;
 
816
              goto out;
 
817
            }
 
818
 
 
819
          /* we know that we are leaving the stage here */
 
820
          _clutter_input_device_set_stage (device, NULL);
 
821
          CLUTTER_NOTE (EVENT, "Leaving the stage (time:%u)",
 
822
                        event->crossing.time);
 
823
 
 
824
          event->crossing.type = event->type = CLUTTER_LEAVE;
 
825
          event->crossing.time = xevent->xcrossing.time;
 
826
          event->crossing.x = xevent->xcrossing.x;
 
827
          event->crossing.y = xevent->xcrossing.y;
 
828
          event->crossing.source = CLUTTER_ACTOR (stage);
 
829
          event->crossing.device = device;
 
830
          res = TRUE;
 
831
          break;
 
832
 
 
833
        default:
 
834
          res = FALSE;
 
835
          break;
739
836
        }
740
 
      else
741
 
        {  /* XInput fun.. Needs clean up. */
 
837
    }
 
838
 
 
839
    /* XInput fun...*/
 
840
  if (!res && clutter_x11_has_xinput ())
 
841
    {
742
842
#ifdef HAVE_XINPUT
743
 
          int *ev_types = backend_x11->event_types;
744
 
 
745
 
          CLUTTER_NOTE (EVENT, "XInput event type: %d", xevent->type);
746
 
 
747
 
          if (xevent->type == ev_types [CLUTTER_X11_XINPUT_BUTTON_PRESS_EVENT])
748
 
            {
749
 
              XDeviceButtonEvent *xbev = (XDeviceButtonEvent *) xevent;
750
 
 
751
 
              CLUTTER_NOTE (EVENT, "XINPUT Button press event for %li at %d, %d",
752
 
                            xbev->deviceid,
753
 
                            xbev->x,
754
 
                            xbev->y);
755
 
 
756
 
              switch (xbev->button)
757
 
                {
758
 
                case 4:
759
 
                case 5:
760
 
                case 6:
761
 
                case 7:
762
 
                  event->scroll.type = event->type = CLUTTER_SCROLL;
763
 
                  
764
 
                  if (xbev->button == 4)
765
 
                    event->scroll.direction = CLUTTER_SCROLL_UP;
766
 
                  else if (xbev->button == 5)
767
 
                    event->scroll.direction = CLUTTER_SCROLL_DOWN;
768
 
                  else if (xbev->button == 6)
769
 
                    event->scroll.direction = CLUTTER_SCROLL_LEFT;
770
 
                  else
771
 
                    event->scroll.direction = CLUTTER_SCROLL_RIGHT;
772
 
                  
773
 
                  event->scroll.time = xbev->time;
774
 
                  event->scroll.x = xbev->x;
775
 
                  event->scroll.y = xbev->y;
776
 
                  event->scroll.modifier_state = xbev->state;
777
 
                  event->scroll.device = _clutter_x11_get_device_for_xid (xbev->deviceid);
778
 
                  break;
779
 
 
780
 
                default:
781
 
                  event->button.type = event->type = CLUTTER_BUTTON_PRESS;
782
 
                  event->button.time = xbev->time;
783
 
                  event->button.x = xbev->x;
784
 
                  event->button.y = xbev->y;
785
 
                  event->button.modifier_state = xbev->state;
786
 
                  event->button.button = xbev->button;
787
 
                  event->button.device = _clutter_x11_get_device_for_xid (xbev->deviceid);
788
 
                  break;
789
 
                }
790
 
 
791
 
              set_user_time (backend_x11, &xwindow, xbev->time);
792
 
            } 
793
 
          else if (xevent->type 
794
 
                        == ev_types[CLUTTER_X11_XINPUT_BUTTON_RELEASE_EVENT])
795
 
            {
796
 
              XDeviceButtonEvent *xbev = (XDeviceButtonEvent *)xevent;
797
 
 
798
 
              CLUTTER_NOTE (EVENT, "XINPUT Button release event for %li at %d, %d",
799
 
                            xbev->deviceid,
800
 
                            xbev->x,
801
 
                            xbev->y);
802
 
 
803
 
              /* scroll events don't have a corresponding release */
804
 
              if (xbev->button == 4 ||
805
 
                  xbev->button == 5 ||
806
 
                  xbev->button == 6 ||
807
 
                  xbev->button == 7)
808
 
                {
809
 
                  return FALSE;
810
 
                }
811
 
 
812
 
              event->button.type = event->type = CLUTTER_BUTTON_RELEASE;
 
843
      int *ev_types = backend_x11->event_types;
 
844
      int button_press, button_release;
 
845
      int key_press, key_release;
 
846
      int motion_notify;
 
847
 
 
848
      button_press   = ev_types[CLUTTER_X11_XINPUT_BUTTON_PRESS_EVENT];
 
849
      button_release = ev_types[CLUTTER_X11_XINPUT_BUTTON_RELEASE_EVENT];
 
850
      motion_notify  = ev_types[CLUTTER_X11_XINPUT_MOTION_NOTIFY_EVENT];
 
851
      key_press      = ev_types[CLUTTER_X11_XINPUT_KEY_PRESS_EVENT];
 
852
      key_release    = ev_types[CLUTTER_X11_XINPUT_KEY_RELEASE_EVENT];
 
853
 
 
854
      CLUTTER_NOTE (EVENT, "XInput event type: %d", xevent->type);
 
855
 
 
856
      if (xevent->type == button_press)
 
857
        {
 
858
          XDeviceButtonEvent *xbev = (XDeviceButtonEvent *) xevent;
 
859
 
 
860
          device = _clutter_x11_get_device_for_xid (xbev->deviceid);
 
861
          _clutter_input_device_set_stage (device, stage);
 
862
 
 
863
          CLUTTER_NOTE (EVENT,
 
864
                        "XI ButtonPress for %li ('%s') at %d, %d",
 
865
                        xbev->deviceid,
 
866
                        device->device_name,
 
867
                        xbev->x,
 
868
                        xbev->y);
 
869
 
 
870
          switch (xbev->button)
 
871
            {
 
872
            case 4:
 
873
            case 5:
 
874
            case 6:
 
875
            case 7:
 
876
              event->scroll.type = event->type = CLUTTER_SCROLL;
 
877
 
 
878
              if (xbev->button == 4)
 
879
                event->scroll.direction = CLUTTER_SCROLL_UP;
 
880
              else if (xbev->button == 5)
 
881
                event->scroll.direction = CLUTTER_SCROLL_DOWN;
 
882
              else if (xbev->button == 6)
 
883
                event->scroll.direction = CLUTTER_SCROLL_LEFT;
 
884
              else
 
885
                event->scroll.direction = CLUTTER_SCROLL_RIGHT;
 
886
 
 
887
              event->scroll.time = xbev->time;
 
888
              event->scroll.x = xbev->x;
 
889
              event->scroll.y = xbev->y;
 
890
              event->scroll.modifier_state = xbev->state;
 
891
              event->scroll.device = device;
 
892
              break;
 
893
 
 
894
            default:
 
895
              event->button.type = event->type = CLUTTER_BUTTON_PRESS;
813
896
              event->button.time = xbev->time;
814
897
              event->button.x = xbev->x;
815
898
              event->button.y = xbev->y;
816
899
              event->button.modifier_state = xbev->state;
817
900
              event->button.button = xbev->button;
818
 
              event->button.device = _clutter_x11_get_device_for_xid (xbev->deviceid);
819
 
            } 
820
 
          else if (xevent->type 
821
 
                       == ev_types [CLUTTER_X11_XINPUT_MOTION_NOTIFY_EVENT]) 
822
 
            {
823
 
              XDeviceMotionEvent *xmev = (XDeviceMotionEvent *)xevent;
824
 
 
825
 
              CLUTTER_NOTE(EVENT, "XINPUT Motion event for %li at %d, %d",
826
 
                           xmev->deviceid,
827
 
                           xmev->x,
828
 
                           xmev->y);
829
 
 
830
 
              event->motion.type = event->type = CLUTTER_MOTION;
831
 
              event->motion.time = xmev->time;
832
 
              event->motion.x = xmev->x;
833
 
              event->motion.y = xmev->y;
834
 
              event->motion.modifier_state = xmev->state;
835
 
              event->motion.device = _clutter_x11_get_device_for_xid (xmev->deviceid);
836
 
            } 
837
 
#if 0
838
 
        /* the Xinput handling of key presses/releases disabled for now since
839
 
         * it makes keyrepeat, and key presses and releases outside the window
840
 
         * not generate events even when the window has focus
841
 
         */
842
 
 
843
 
          else if (xevent->type 
844
 
                        == ev_types [CLUTTER_X11_XINPUT_KEY_PRESS_EVENT]) 
845
 
            {
846
 
              XEvent xevent_converted;
847
 
              XDeviceKeyEvent *xkev = (XDeviceKeyEvent *)xevent;
848
 
              
849
 
              convert_xdevicekey_to_xkey (xkev, &xevent_converted);
850
 
 
851
 
              event->key.type = event->type = CLUTTER_KEY_PRESS;
852
 
              translate_key_event (backend, event, &xevent_converted);
853
 
 
854
 
              set_user_time (backend_x11, &xwindow, xkev->time);
855
 
            } 
856
 
          else if (xevent->type 
857
 
                   == ev_types [CLUTTER_X11_XINPUT_KEY_RELEASE_EVENT]) 
858
 
            {
859
 
              XEvent xevent_converted;
860
 
              XDeviceKeyEvent *xkev = (XDeviceKeyEvent *)xevent;
861
 
              
862
 
              convert_xdevicekey_to_xkey (xkev, &xevent_converted);
863
 
 
864
 
              event->key.type = event->type = CLUTTER_KEY_RELEASE;
865
 
              translate_key_event (backend, event, &xevent_converted);
866
 
            }
867
 
#endif
868
 
          else 
 
901
              event->button.device = device;
 
902
              break;
 
903
            }
 
904
 
 
905
          set_user_time (backend_x11, &xwindow, xbev->time);
 
906
 
 
907
          res = TRUE;
 
908
        }
 
909
      else if (xevent->type == button_release)
 
910
        {
 
911
          XDeviceButtonEvent *xbev = (XDeviceButtonEvent *)xevent;
 
912
 
 
913
          device = _clutter_x11_get_device_for_xid (xbev->deviceid);
 
914
          _clutter_input_device_set_stage (device, stage);
 
915
 
 
916
          CLUTTER_NOTE (EVENT, "XI ButtonRelease for %li ('%s') at %d, %d",
 
917
                        xbev->deviceid,
 
918
                        device->device_name,
 
919
                        xbev->x,
 
920
                        xbev->y);
 
921
 
 
922
          /* scroll events don't have a corresponding release */
 
923
          if (xbev->button == 4 ||
 
924
              xbev->button == 5 ||
 
925
              xbev->button == 6 ||
 
926
              xbev->button == 7)
 
927
            {
 
928
              res = FALSE;
 
929
              goto out;
 
930
            }
 
931
 
 
932
          event->button.type = event->type = CLUTTER_BUTTON_RELEASE;
 
933
          event->button.time = xbev->time;
 
934
          event->button.x = xbev->x;
 
935
          event->button.y = xbev->y;
 
936
          event->button.modifier_state = xbev->state;
 
937
          event->button.button = xbev->button;
 
938
          event->button.device = device;
 
939
 
 
940
          res = TRUE;
 
941
        }
 
942
      else if (xevent->type == motion_notify)
 
943
        {
 
944
          XDeviceMotionEvent *xmev = (XDeviceMotionEvent *)xevent;
 
945
 
 
946
          device = _clutter_x11_get_device_for_xid (xmev->deviceid);
 
947
          _clutter_input_device_set_stage (device, stage);
 
948
 
 
949
          CLUTTER_NOTE (EVENT, "XI Motion for %li ('%s') at %d, %d",
 
950
                        xmev->deviceid,
 
951
                        device->device_name,
 
952
                        xmev->x,
 
953
                        xmev->y);
 
954
 
 
955
          event->motion.type = event->type = CLUTTER_MOTION;
 
956
          event->motion.time = xmev->time;
 
957
          event->motion.x = xmev->x;
 
958
          event->motion.y = xmev->y;
 
959
          event->motion.modifier_state = xmev->state;
 
960
          event->motion.device = device;
 
961
 
 
962
          res = TRUE;
 
963
        }
 
964
      else if (xevent->type == key_press || xevent->type == key_release)
 
965
        {
 
966
          /* the XInput 1.x handling of key presses/releases is broken:
 
967
           * it makes key repeat, key presses and releases outside the
 
968
           * window not generate events even when the window has focus
 
969
           */
 
970
          XDeviceKeyEvent *xkev = (XDeviceKeyEvent *) xevent;
 
971
          XEvent xevent_converted;
 
972
 
 
973
          convert_xdevicekey_to_xkey (xkev, &xevent_converted);
 
974
 
 
975
          event->key.type = event->type = (xevent->type == key_press)
 
976
                                          ? CLUTTER_KEY_PRESS
 
977
                                          : CLUTTER_KEY_RELEASE;
 
978
 
 
979
          translate_key_event (backend, event, &xevent_converted);
 
980
 
 
981
          if (xevent->type == key_press)
 
982
            set_user_time (backend_x11, &xwindow, xkev->time);
 
983
        }
 
984
      else
869
985
#endif /* HAVE_XINPUT */
870
 
            {
871
 
              CLUTTER_NOTE (EVENT, "Uknown Event");
872
 
              res = FALSE;
873
 
            }
 
986
        {
 
987
          CLUTTER_NOTE (EVENT, "Uknown Event");
 
988
          res = FALSE;
874
989
        }
875
990
    }
876
991
 
 
992
out:
877
993
  return res;
878
994
}
879
995
 
881
997
events_queue (ClutterBackend *backend)
882
998
{
883
999
  ClutterBackendX11 *backend_x11 = CLUTTER_BACKEND_X11 (backend);
 
1000
  ClutterBackendX11Class *backend_x11_class =
 
1001
    CLUTTER_BACKEND_X11_GET_CLASS (backend_x11);
884
1002
  ClutterEvent      *event;
885
1003
  Display           *xdisplay = backend_x11->xdpy;
886
1004
  XEvent             xevent;
892
1010
    {
893
1011
      XNextEvent (xdisplay, &xevent);
894
1012
 
 
1013
      if (backend_x11_class->handle_event (backend_x11, &xevent))
 
1014
        continue;
 
1015
 
895
1016
      event = clutter_event_new (CLUTTER_NOTHING);
896
1017
 
897
1018
      if (event_translate (backend, event, &xevent))