~ubuntu-branches/ubuntu/precise/gtk+2.0/precise-updates

« back to all changes in this revision

Viewing changes to gdk/win32/gdkinput-win32.c

  • Committer: Package Import Robot
  • Author(s): Ken VanDine
  • Date: 2011-12-01 11:40:06 UTC
  • mfrom: (1.14.11)
  • Revision ID: package-import@ubuntu.com-20111201114006-nrmf6qu3pg512veo
Tags: 2.24.8-0ubuntu1
* New upstream release 
  - gtkfilechooser should be more robust to malformed URIs
    in .gtk-bookmarks (LP: #189494)
* debian/patches/010_make_bg_changes_queue_repaint.patch
  - dropped it introduces performance regressions in some gtk2 
    apps (LP: #889019)
* 101_filechooser.patch, 000git_file_chooser.patch: dropped, upstream

Show diffs side-by-side

added added

removed removed

Lines of Context:
58
58
 
59
59
static GdkWindow *wintab_window = NULL;
60
60
 
61
 
static GdkWindow *x_grab_window = NULL; /* Window that currently holds
62
 
                                         * the extended inputs grab
63
 
                                         */
64
 
static GdkEventMask x_grab_mask;
65
 
static gboolean x_grab_owner_events;
 
61
static GdkDevicePrivate *_gdk_device_in_proximity;
66
62
 
67
63
typedef UINT (WINAPI *t_WTInfoA) (UINT a, UINT b, LPVOID c);
68
64
typedef UINT (WINAPI *t_WTInfoW) (UINT a, UINT b, LPVOID c);
69
65
typedef BOOL (WINAPI *t_WTEnable) (HCTX a, BOOL b);
70
66
typedef HCTX (WINAPI *t_WTOpenA) (HWND a, LPLOGCONTEXTA b, BOOL c);
 
67
typedef BOOL (WINAPI *t_WTGetA) (HCTX a, LPLOGCONTEXTA b);
 
68
typedef BOOL (WINAPI *t_WTSetA) (HCTX a, LPLOGCONTEXTA b);
71
69
typedef BOOL (WINAPI *t_WTOverlap) (HCTX a, BOOL b);
72
70
typedef BOOL (WINAPI *t_WTPacket) (HCTX a, UINT b, LPVOID c);
73
71
typedef int (WINAPI *t_WTQueueSizeSet) (HCTX a, int b);
76
74
static t_WTInfoW p_WTInfoW;
77
75
static t_WTEnable p_WTEnable;
78
76
static t_WTOpenA p_WTOpenA;
 
77
static t_WTGetA p_WTGetA;
 
78
static t_WTSetA p_WTSetA;
79
79
static t_WTOverlap p_WTOverlap;
80
80
static t_WTPacket p_WTPacket;
81
81
static t_WTQueueSizeSet p_WTQueueSizeSet;
97
97
  return NULL;
98
98
}
99
99
 
 
100
 
100
101
#if DEBUG_WINTAB
101
102
 
 
103
#ifdef G_ENABLE_DEBUG
102
104
static void
103
105
print_lc(LOGCONTEXT *lc)
104
106
{
323
325
    }
324
326
}
325
327
#endif
 
328
#endif
326
329
 
327
330
void
328
331
_gdk_input_wintab_init_check (void)
384
387
    return;
385
388
  if ((p_WTOpenA = (t_WTOpenA) GetProcAddress (wintab32, "WTOpenA")) == NULL)
386
389
    return;
 
390
  if ((p_WTGetA = (t_WTGetA) GetProcAddress (wintab32, "WTGetA")) == NULL)
 
391
    return;
 
392
  if ((p_WTSetA = (t_WTSetA) GetProcAddress (wintab32, "WTSetA")) == NULL)
 
393
    return;
387
394
  if ((p_WTOverlap = (t_WTOverlap) GetProcAddress (wintab32, "WTOverlap")) == NULL)
388
395
    return;
389
396
  if ((p_WTPacket = (t_WTPacket) GetProcAddress (wintab32, "WTPacket")) == NULL)
461
468
#if DEBUG_WINTAB
462
469
      GDK_NOTE (INPUT, (g_print("Default context:\n"), print_lc(&lc)));
463
470
#endif
464
 
      lc.lcOptions |= CXO_MESSAGES;
 
471
      lc.lcOptions |= CXO_MESSAGES | CXO_CSRMESSAGES;
465
472
      lc.lcStatus = 0;
466
473
      lc.lcMsgBase = WT_DEFBASE;
467
474
      lc.lcPktRate = 0;
471
478
      lc.lcBtnUpMask = lc.lcBtnDnMask = ~0;
472
479
      lc.lcOutOrgX = axis_x.axMin;
473
480
      lc.lcOutOrgY = axis_y.axMin;
474
 
      lc.lcOutExtX = axis_x.axMax - axis_x.axMin;
475
 
      lc.lcOutExtY = axis_y.axMax - axis_y.axMin;
 
481
      lc.lcOutExtX = axis_x.axMax - axis_x.axMin + 1;
 
482
      lc.lcOutExtY = axis_y.axMax - axis_y.axMin + 1;
476
483
      lc.lcOutExtY = -lc.lcOutExtY; /* We want Y growing downward */
477
484
#if DEBUG_WINTAB
478
485
      GDK_NOTE (INPUT, (g_print("context for device %d:\n", devix),
488
495
                                devix, *hctx));
489
496
      
490
497
      wintab_contexts = g_list_append (wintab_contexts, hctx);
491
 
#if 0
492
 
      (*p_WTEnable) (*hctx, TRUE);
493
 
#endif
 
498
 
494
499
      (*p_WTOverlap) (*hctx, TRUE);
495
500
 
496
501
#if DEBUG_WINTAB
502
507
       * with a smaller queue size.
503
508
       */
504
509
      GDK_NOTE (INPUT, g_print("Attempting to increase queue size\n"));
505
 
      for (i = 32; i >= 1; i >>= 1)
 
510
      for (i = 128; i >= 1; i >>= 1)
506
511
        {
507
512
          if ((*p_WTQueueSizeSet) (*hctx, i))
508
513
            {
615
620
                  gdkdev->axes[k].min_value = -1000;
616
621
                  gdkdev->axes[k].max_value = 1000;
617
622
                  gdkdev->info.axes[k].use = axis;
618
 
                  gdkdev->info.axes[k].min = -1000;
619
 
                  gdkdev->info.axes[k].max = 1000;
 
623
                  gdkdev->info.axes[k].min = -1.0;
 
624
                  gdkdev->info.axes[k].max = 1.0;
620
625
                  k++;
621
626
                }
622
627
            }
663
668
 
664
669
static void
665
670
gdk_input_translate_coordinates (GdkDevicePrivate *gdkdev,
666
 
                                 GdkInputWindow   *input_window,
 
671
                                 GdkWindow        *window,
667
672
                                 gint             *axis_data,
668
673
                                 gdouble          *axis_out,
669
674
                                 gdouble          *x_out,
670
675
                                 gdouble          *y_out)
671
676
{
 
677
  GdkWindowObject *priv, *impl_window;
672
678
  GdkWindowImplWin32 *root_impl;
673
 
  GdkWindowObject *window_object;
674
679
 
675
680
  int i;
676
681
  int x_axis = 0;
677
682
  int y_axis = 0;
678
683
 
679
 
  double device_width, device_height;
 
684
  double device_width, device_height, x_min, y_min;
680
685
  double x_offset, y_offset, x_scale, y_scale;
681
686
 
682
 
  window_object = GDK_WINDOW_OBJECT (input_window);
 
687
  priv = (GdkWindowObject *) window;
 
688
  impl_window = (GdkWindowObject *)_gdk_window_get_impl_window (window);
683
689
 
684
690
  for (i=0; i<gdkdev->info.num_axes; i++)
685
691
    {
686
692
      switch (gdkdev->info.axes[i].use)
687
 
                {
688
 
                case GDK_AXIS_X:
689
 
                  x_axis = i;
690
 
                  break;
691
 
                case GDK_AXIS_Y:
692
 
                  y_axis = i;
693
 
                  break;
694
 
                default:
695
 
                  break;
696
 
                }
 
693
        {
 
694
        case GDK_AXIS_X:
 
695
          x_axis = i;
 
696
          break;
 
697
        case GDK_AXIS_Y:
 
698
          y_axis = i;
 
699
          break;
 
700
        default:
 
701
          break;
 
702
        }
697
703
    }
698
704
  
699
705
  device_width = gdkdev->axes[x_axis].max_value - gdkdev->axes[x_axis].min_value;
 
706
  x_min = gdkdev->axes[x_axis].min_value;
700
707
  device_height = gdkdev->axes[y_axis].max_value - gdkdev->axes[y_axis].min_value;
 
708
  y_min = gdkdev->axes[y_axis].min_value;
701
709
 
702
710
  if (gdkdev->info.mode == GDK_MODE_SCREEN) 
703
711
    {
705
713
      x_scale = GDK_WINDOW_OBJECT (_gdk_root)->width / device_width;
706
714
      y_scale = GDK_WINDOW_OBJECT (_gdk_root)->height / device_height;
707
715
 
708
 
      x_offset = - input_window->root_x;
709
 
      y_offset = - input_window->root_y;
 
716
      x_offset = - impl_window->input_window->root_x - priv->abs_x;
 
717
      y_offset = - impl_window->input_window->root_y - priv->abs_y;
710
718
    }
711
719
  else                          /* GDK_MODE_WINDOW */
712
720
    {
713
 
      double device_aspect = (device_height*gdkdev->axes[y_axis].resolution) /
714
 
        (device_width*gdkdev->axes[x_axis].resolution);
715
 
 
716
 
      if (device_aspect * window_object->width >= window_object->height)
717
 
                {
718
 
                  /* device taller than window */
719
 
                  x_scale = window_object->width / device_width;
720
 
                  y_scale = (x_scale * gdkdev->axes[x_axis].resolution) / gdkdev->axes[y_axis].resolution;
721
 
 
722
 
                  x_offset = 0;
723
 
                  y_offset = -(device_height * y_scale - window_object->height) / 2;
724
 
                }
 
721
      double x_resolution = gdkdev->axes[x_axis].resolution;
 
722
      double y_resolution = gdkdev->axes[y_axis].resolution;
 
723
      double device_aspect = (device_height*y_resolution) / (device_width * x_resolution);
 
724
 
 
725
      if (device_aspect * priv->width >= priv->height)
 
726
        {
 
727
          /* device taller than window */
 
728
          x_scale = priv->width / device_width;
 
729
          y_scale = (x_scale * x_resolution) / y_resolution;
 
730
 
 
731
          x_offset = 0;
 
732
          y_offset = -(device_height * y_scale - priv->height) / 2;
 
733
        }
725
734
      else
726
 
                {
727
 
                  /* window taller than device */
728
 
                  y_scale = window_object->height / device_height;
729
 
                  x_scale = (y_scale * gdkdev->axes[y_axis].resolution)
730
 
                        / gdkdev->axes[x_axis].resolution;
 
735
        {
 
736
          /* window taller than device */
 
737
          y_scale = priv->height / device_height;
 
738
          x_scale = (y_scale * y_resolution)  / x_resolution;
731
739
 
732
 
                  y_offset = 0;
733
 
                  x_offset = - (device_width * x_scale - window_object->width) / 2;
734
 
                }
 
740
          y_offset = 0;
 
741
          x_offset = - (device_width * x_scale - priv->width) / 2;
 
742
        }
735
743
    }
736
744
 
737
745
  for (i = 0; i < gdkdev->info.num_axes; i++)
738
746
    {
739
747
      switch (gdkdev->info.axes[i].use)
740
 
                {
741
 
                case GDK_AXIS_X:
742
 
                  axis_out[i] = x_offset + x_scale * axis_data[x_axis];
743
 
                  if (x_out)
744
 
                        *x_out = axis_out[i];
745
 
                  break;
746
 
                case GDK_AXIS_Y:
747
 
                  axis_out[i] = y_offset + y_scale * axis_data[y_axis];
748
 
                  if (y_out)
749
 
                        *y_out = axis_out[i];
750
 
                  break;
751
 
                default:
752
 
                  axis_out[i] =
753
 
                        (gdkdev->info.axes[i].max * (axis_data[i] - gdkdev->axes[i].min_value) +
754
 
                         gdkdev->info.axes[i].min * (gdkdev->axes[i].max_value - axis_data[i])) /
755
 
                        (gdkdev->axes[i].max_value - gdkdev->axes[i].min_value);
756
 
                  break;
757
 
                }
 
748
        {
 
749
        case GDK_AXIS_X:
 
750
          axis_out[i] = x_offset + x_scale * axis_data[x_axis];
 
751
          if (x_out)
 
752
            *x_out = axis_out[i];
 
753
          break;
 
754
        case GDK_AXIS_Y:
 
755
          axis_out[i] = y_offset + y_scale * axis_data[y_axis];
 
756
          if (y_out)
 
757
            *y_out = axis_out[i];
 
758
          break;
 
759
        default:
 
760
          axis_out[i] =
 
761
            (gdkdev->info.axes[i].max * (axis_data[i] - gdkdev->axes[i].min_value) +
 
762
             gdkdev->info.axes[i].min * (gdkdev->axes[i].max_value - axis_data[i])) /
 
763
            (gdkdev->axes[i].max_value - gdkdev->axes[i].min_value);
 
764
          break;
 
765
        }
758
766
    }
759
767
}
760
768
 
763
771
                                      int  *x_ret,
764
772
                                      int  *y_ret)
765
773
{
766
 
  RECT rect;
 
774
  POINT pt;
767
775
 
768
 
  GetWindowRect (w, &rect);
 
776
  pt.x = 0;
 
777
  pt.y = 0;
 
778
  ClientToScreen (w, &pt);
769
779
 
770
780
  if (x_ret)
771
 
    *x_ret = rect.left + _gdk_offset_x;
 
781
    *x_ret = pt.x + _gdk_offset_x;
772
782
  if (y_ret)
773
 
    *y_ret = rect.top + _gdk_offset_y;
 
783
    *y_ret = pt.y + _gdk_offset_y;
774
784
}
775
785
 
776
786
void
777
787
_gdk_input_configure_event (GdkWindow         *window)
778
788
{
779
789
  GdkInputWindow *input_window;
 
790
  GdkWindowObject *impl_window;
780
791
  int root_x, root_y;
781
792
 
782
 
  input_window = _gdk_input_window_find (window);
783
793
  g_return_if_fail (window != NULL);
784
794
 
 
795
  impl_window = (GdkWindowObject *)_gdk_window_get_impl_window (window);
 
796
  input_window = impl_window->input_window;
 
797
 
785
798
  gdk_input_get_root_relative_geometry (GDK_WINDOW_HWND (window),
786
799
                                        &root_x, &root_y);
787
800
 
789
802
  input_window->root_y = root_y;
790
803
}
791
804
 
792
 
void 
793
 
_gdk_input_enter_event (GdkWindow        *window)
794
 
{
795
 
  GdkInputWindow *input_window;
796
 
  int root_x, root_y;
797
 
 
798
 
  input_window = _gdk_input_window_find (window);
799
 
  g_return_if_fail (window != NULL);
800
 
 
801
 
  gdk_input_get_root_relative_geometry (GDK_WINDOW_HWND (window), &root_x, &root_y);
802
 
 
803
 
  input_window->root_x = root_x;
804
 
  input_window->root_y = root_y;
805
 
}
806
 
 
807
805
/*
808
806
 * Get the currently active keyboard modifiers (ignoring the mouse buttons)
809
807
 * We could use gdk_window_get_pointer but that function does a lot of other
829
827
  return state;
830
828
}
831
829
 
 
830
#if 0
832
831
static guint ignore_core_timer = 0;
833
832
 
834
833
static gboolean
867
866
                                         ignore_core_timefunc, NULL);
868
867
}
869
868
 
 
869
#endif
 
870
 
 
871
void
 
872
_gdk_input_update_for_device_mode (GdkDevicePrivate *gdkdev)
 
873
{
 
874
  LOGCONTEXT lc;
 
875
 
 
876
  if (gdkdev != _gdk_device_in_proximity)
 
877
    return;
 
878
 
 
879
  if (p_WTGetA (gdkdev->hctx, &lc))
 
880
    {
 
881
      if (gdkdev->info.mode == GDK_MODE_SCREEN &&
 
882
          (lc.lcOptions & CXO_SYSTEM) == 0)
 
883
        {
 
884
          lc.lcOptions |= CXO_SYSTEM;
 
885
          p_WTSetA (gdkdev->hctx, &lc);
 
886
        }
 
887
      else if (gdkdev->info.mode == GDK_MODE_WINDOW &&
 
888
               (lc.lcOptions & CXO_SYSTEM) != 0)
 
889
        {
 
890
          lc.lcOptions &= ~CXO_SYSTEM;
 
891
          p_WTSetA (gdkdev->hctx, &lc);
 
892
        }
 
893
    }
 
894
}
 
895
 
 
896
static GdkWindow *
 
897
find_window_for_input_event (MSG* msg, int *x, int *y)
 
898
{
 
899
  POINT pt;
 
900
  GdkWindow *window;
 
901
  HWND hwnd;
 
902
  RECT rect;
 
903
 
 
904
  pt = msg->pt;
 
905
 
 
906
  window = NULL;
 
907
  hwnd = WindowFromPoint (pt);
 
908
  if (hwnd != NULL)
 
909
    {
 
910
      POINT client_pt = pt;
 
911
 
 
912
      ScreenToClient (hwnd, &client_pt);
 
913
      GetClientRect (hwnd, &rect);
 
914
      if (PtInRect (&rect, client_pt))
 
915
        window = gdk_win32_handle_table_lookup ((GdkNativeWindow) hwnd);
 
916
    }
 
917
 
 
918
  /* need to also adjust the coordinates to the new window */
 
919
  if (window)
 
920
    ScreenToClient (GDK_WINDOW_HWND (window), &pt);
 
921
 
 
922
  *x = pt.x;
 
923
  *y = pt.y;
 
924
 
 
925
  if (window)
 
926
    return window;
 
927
 
 
928
  return _gdk_root;
 
929
}
 
930
 
870
931
gboolean 
871
932
_gdk_input_other_event (GdkEvent  *event,
872
933
                        MSG       *msg,
873
934
                        GdkWindow *window)
874
935
{
875
 
  GdkDisplay *display;
876
 
  GdkWindowObject *obj, *grab_obj;
 
936
  GdkWindowObject *obj, *impl_window;
 
937
  GdkWindow *native_window;
877
938
  GdkInputWindow *input_window;
878
939
  GdkDevicePrivate *gdkdev = NULL;
879
 
  GdkEventMask masktest;
880
940
  guint key_state;
881
 
  POINT pt;
882
941
 
883
942
  PACKET packet;
884
943
  gint k;
889
948
   */
890
949
  static guint button_map[8] = {0, 1, 4, 5, 2, 3, 6, 7};
891
950
 
892
 
  if (event->any.window != wintab_window)
 
951
  if (window != wintab_window)
893
952
    {
894
953
      g_warning ("_gdk_input_other_event: not wintab_window?");
895
954
      return FALSE;
896
955
    }
897
956
 
898
 
  window = gdk_window_at_pointer (&x, &y);
899
 
  if (window == NULL)
900
 
    window = _gdk_root;
901
 
 
902
 
  g_object_ref (window);
903
 
  display = gdk_drawable_get_display (window);
 
957
  native_window = find_window_for_input_event (msg, &x, &y);
904
958
 
905
959
  GDK_NOTE (EVENTS_OR_INPUT,
906
 
            g_print ("_gdk_input_other_event: window=%p %+d%+d\n",
907
 
                     GDK_WINDOW_HWND (window), x, y));
908
 
  
909
 
  if (msg->message == WT_PACKET)
 
960
            g_print ("_gdk_input_other_event: native_window=%p %+d%+d\n",
 
961
                     GDK_WINDOW_HWND (native_window), x, y));
 
962
 
 
963
  if (msg->message == WT_PACKET || msg->message == WT_CSRCHANGE)
910
964
    {
911
965
      if (!(*p_WTPacket) ((HCTX) msg->lParam, msg->wParam, &packet))
912
966
        return FALSE;
913
967
    }
914
968
 
915
 
  obj = GDK_WINDOW_OBJECT (window);
916
 
 
917
969
  switch (msg->message)
918
970
    {
919
971
    case WT_PACKET:
925
977
          GDK_NOTE (EVENTS_OR_INPUT, g_print ("... ignored when moving/sizing\n"));
926
978
          return FALSE;
927
979
        }
928
 
      if (window == _gdk_root && x_grab_window == NULL)
929
 
        {
930
 
          GDK_NOTE (EVENTS_OR_INPUT, g_print ("... is root\n"));
931
 
          return FALSE;
932
 
        }
933
980
 
934
981
      if ((gdkdev = gdk_input_find_dev_from_ctx ((HCTX) msg->lParam,
935
982
                                                 packet.pkCursor)) == NULL)
979
1026
            }
980
1027
 
981
1028
          if (!(translated_buttons & button_mask))
982
 
            {
983
 
              event->any.type = GDK_BUTTON_RELEASE;
984
 
              masktest = GDK_BUTTON_RELEASE_MASK;
985
 
            }
 
1029
            event->any.type = GDK_BUTTON_RELEASE;
986
1030
          else
987
 
            {
988
 
              event->any.type = GDK_BUTTON_PRESS;
989
 
              masktest = GDK_BUTTON_PRESS_MASK;
990
 
            }
 
1031
            event->any.type = GDK_BUTTON_PRESS;
991
1032
          gdkdev->button_state ^= button_mask;
992
1033
        }
993
1034
      else
994
1035
        {
995
1036
          event->any.type = GDK_MOTION_NOTIFY;
996
 
          masktest = GDK_POINTER_MOTION_MASK;
997
 
          if (gdkdev->button_state & (1 << 0))
998
 
            masktest |= GDK_BUTTON_MOTION_MASK | GDK_BUTTON1_MOTION_MASK;
999
 
          if (gdkdev->button_state & (1 << 1))
1000
 
            masktest |= GDK_BUTTON_MOTION_MASK | GDK_BUTTON2_MOTION_MASK;
1001
 
          if (gdkdev->button_state & (1 << 2))
1002
 
            masktest |= GDK_BUTTON_MOTION_MASK | GDK_BUTTON3_MOTION_MASK;
1003
 
        }
1004
 
 
1005
 
      /* See if input is grabbed */
1006
 
      /* FIXME: x_grab_owner_events should probably be handled somehow */
1007
 
      if (x_grab_window != NULL)
1008
 
        {
1009
 
          grab_obj = GDK_WINDOW_OBJECT (x_grab_window);
1010
 
          if (!GDK_WINDOW_IMPL_WIN32 (grab_obj->impl)->extension_events_selected
1011
 
              || !(grab_obj->extension_events & masktest)
1012
 
              || !(x_grab_mask && masktest))
1013
 
            {
1014
 
              GDK_NOTE (EVENTS_OR_INPUT, 
1015
 
                        g_print ("... grabber doesn't want it\n"));
1016
 
              return FALSE;
1017
 
            }
1018
 
          GDK_NOTE (EVENTS_OR_INPUT, g_print ("... to grabber\n"));
1019
 
 
1020
 
          g_object_ref(x_grab_window);
1021
 
          g_object_unref(window);
1022
 
          window = x_grab_window;
1023
 
          obj = grab_obj;
1024
 
        }
1025
 
      /* Now we can check if the window wants the event, and
1026
 
       * propagate if necessary.
1027
 
       */
1028
 
    loop:
1029
 
      if (!GDK_WINDOW_IMPL_WIN32 (obj->impl)->extension_events_selected
1030
 
          || !(obj->extension_events & masktest))
1031
 
        {
1032
 
          GDK_NOTE (EVENTS_OR_INPUT, g_print ("... not selected\n"));
1033
 
 
1034
 
          if (obj->parent == GDK_WINDOW_OBJECT (_gdk_root))
1035
 
            return FALSE;
1036
 
 
1037
 
          /* It is not good to propagate the extended events up to the parent
1038
 
           * if this window wants normal (not extended) motion/button events */
1039
 
          if (obj->event_mask & masktest)
1040
 
            {
1041
 
              GDK_NOTE (EVENTS_OR_INPUT, 
1042
 
                        g_print ("... wants ordinary event, ignoring this\n"));
1043
 
              return FALSE;
1044
 
            }
1045
 
          
1046
 
          pt.x = x;
1047
 
          pt.y = y;
1048
 
          ClientToScreen (GDK_WINDOW_HWND (window), &pt);
1049
 
          g_object_unref (window);
1050
 
          window = (GdkWindow *) obj->parent;
1051
 
          obj = GDK_WINDOW_OBJECT (window);
1052
 
          g_object_ref (window);
1053
 
          ScreenToClient (GDK_WINDOW_HWND (window), &pt);
1054
 
          x = pt.x;
1055
 
          y = pt.y;
1056
 
          GDK_NOTE (EVENTS_OR_INPUT, g_print ("... propagating to %p %+d%+d\n",
1057
 
                                              GDK_WINDOW_HWND (window), x, y));
1058
 
          goto loop;
1059
 
        }
1060
 
 
1061
 
      input_window = _gdk_input_window_find (window);
 
1037
        }
 
1038
 
 
1039
      if (native_window == _gdk_root)
 
1040
        return FALSE;
 
1041
 
 
1042
      window = _gdk_window_get_input_window_for_event (native_window,
 
1043
                                                       event->any.type,
 
1044
                                                       gdkdev->button_state << 8,
 
1045
                                                       x, y, 0);
 
1046
 
 
1047
      obj = GDK_WINDOW_OBJECT (window);
 
1048
 
 
1049
      if (window == NULL ||
 
1050
          obj->extension_events == 0)
 
1051
        return FALSE;
 
1052
      
 
1053
      impl_window = (GdkWindowObject *)_gdk_window_get_impl_window (window);
 
1054
      input_window = impl_window->input_window;
1062
1055
 
1063
1056
      g_assert (input_window != NULL);
1064
1057
 
1065
 
      if (gdkdev->info.mode == GDK_MODE_WINDOW
1066
 
          && input_window->mode == GDK_EXTENSION_EVENTS_CURSOR)
 
1058
      if (gdkdev->info.mode == GDK_MODE_WINDOW && 
 
1059
          (obj->extension_events & GDK_ALL_DEVICES_MASK) == 0)
1067
1060
        return FALSE;
1068
1061
 
1069
1062
      event->any.window = window;
1070
1063
      key_state = get_modifier_key_state ();
1071
 
      if (event->any.type == GDK_BUTTON_PRESS
1072
 
          || event->any.type == GDK_BUTTON_RELEASE)
 
1064
      if (event->any.type == GDK_BUTTON_PRESS || 
 
1065
          event->any.type == GDK_BUTTON_RELEASE)
1073
1066
        {
1074
1067
          event->button.time = _gdk_win32_get_next_tick (msg->time);
1075
1068
          event->button.device = &gdkdev->info;
1076
1069
          
1077
1070
          event->button.axes = g_new(gdouble, gdkdev->info.num_axes);
1078
1071
 
1079
 
          gdk_input_translate_coordinates (gdkdev, input_window,
 
1072
          gdk_input_translate_coordinates (gdkdev, window,
1080
1073
                                           gdkdev->last_axis_data,
1081
1074
                                           event->button.axes,
1082
1075
                                           &event->button.x, 
1107
1100
 
1108
1101
          event->motion.axes = g_new(gdouble, gdkdev->info.num_axes);
1109
1102
 
1110
 
          gdk_input_translate_coordinates (gdkdev, input_window,
 
1103
          gdk_input_translate_coordinates (gdkdev, window,
1111
1104
                                           gdkdev->last_axis_data,
1112
1105
                                           event->motion.axes,
1113
1106
                                           &event->motion.x, 
1130
1123
        }
1131
1124
      return TRUE;
1132
1125
 
 
1126
    case WT_CSRCHANGE:
 
1127
      if ((gdkdev = gdk_input_find_dev_from_ctx ((HCTX) msg->lParam,
 
1128
                                                 packet.pkCursor)) == NULL)
 
1129
        return FALSE;
 
1130
 
 
1131
      _gdk_device_in_proximity = gdkdev;
 
1132
 
 
1133
      _gdk_input_update_for_device_mode (gdkdev);
 
1134
 
 
1135
      window = NULL;
 
1136
      if (native_window != _gdk_root)
 
1137
        window = _gdk_window_get_input_window_for_event (native_window,
 
1138
                                                         GDK_PROXIMITY_IN,
 
1139
                                                         0,
 
1140
                                                         x, y, 0);
 
1141
      if (window)
 
1142
        {
 
1143
          event->proximity.type = GDK_PROXIMITY_IN;
 
1144
          event->proximity.window = window;
 
1145
          event->proximity.time = _gdk_win32_get_next_tick (msg->time);
 
1146
          event->proximity.device = &_gdk_device_in_proximity->info;
 
1147
        }
 
1148
 
 
1149
      GDK_NOTE (EVENTS_OR_INPUT,
 
1150
                g_print ("WINTAB proximity in\n"));
 
1151
 
 
1152
      return TRUE;
 
1153
 
1133
1154
    case WT_PROXIMITY:
 
1155
      /* TODO: Set ignore_core if in input_window */
1134
1156
      if (LOWORD (msg->lParam) == 0)
1135
1157
        {
1136
 
          event->proximity.type = GDK_PROXIMITY_OUT;
1137
 
          set_ignore_core (FALSE);
 
1158
          _gdk_input_in_proximity = FALSE;
 
1159
 
 
1160
          window = NULL;
 
1161
          if (native_window != _gdk_root)
 
1162
            window = _gdk_window_get_input_window_for_event (native_window,
 
1163
                                                             GDK_PROXIMITY_IN,
 
1164
                                                             0,
 
1165
                                                             x, y, 0);
 
1166
          if (window)
 
1167
            {
 
1168
              event->proximity.type = GDK_PROXIMITY_OUT;
 
1169
              event->proximity.window = window;
 
1170
              event->proximity.time = _gdk_win32_get_next_tick (msg->time);
 
1171
              event->proximity.device = &_gdk_device_in_proximity->info;
 
1172
            }
 
1173
 
 
1174
          GDK_NOTE (EVENTS_OR_INPUT,
 
1175
                    g_print ("WINTAB proximity out\n"));
 
1176
 
 
1177
          return TRUE;
1138
1178
        }
1139
1179
      else
1140
 
        {
1141
 
          event->proximity.type = GDK_PROXIMITY_IN;
1142
 
          set_ignore_core (TRUE);
1143
 
        }
1144
 
      event->proximity.time = _gdk_win32_get_next_tick (msg->time);
1145
 
      event->proximity.device = &gdkdev->info;
1146
 
 
1147
 
      GDK_NOTE (EVENTS_OR_INPUT,
1148
 
                g_print ("WINTAB proximity %s\n",
1149
 
                         (event->proximity.type == GDK_PROXIMITY_IN ?
1150
 
                          "in" : "out")));
1151
 
      return TRUE;
 
1180
        _gdk_input_in_proximity = TRUE;
 
1181
 
 
1182
      _gdk_input_check_proximity ();
 
1183
 
 
1184
      break;
1152
1185
    }
1153
1186
  return FALSE;
1154
1187
}
1155
1188
 
1156
 
gboolean
1157
 
_gdk_input_enable_window (GdkWindow        *window,
1158
 
                          GdkDevicePrivate *gdkdev)
1159
 
{
1160
 
  GdkWindowImplWin32 *impl = GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (window)->impl);
1161
 
 
1162
 
  impl->extension_events_selected = TRUE;
1163
 
 
1164
 
  return TRUE;
1165
 
}
1166
 
 
1167
 
gboolean
1168
 
_gdk_input_disable_window (GdkWindow        *window,
1169
 
                           GdkDevicePrivate *gdkdev)
1170
 
{
1171
 
  GdkWindowImplWin32 *impl = GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (window)->impl);
1172
 
 
1173
 
  impl->extension_events_selected = FALSE;
1174
 
 
1175
 
  return TRUE;
 
1189
void
 
1190
_gdk_input_select_events (GdkWindow *impl_window)
 
1191
{
 
1192
  guint event_mask;
 
1193
  GdkWindowObject *w;
 
1194
  GdkInputWindow *iw;
 
1195
  GList *l, *dev_list;
 
1196
  
 
1197
 
 
1198
  iw = ((GdkWindowObject *)impl_window)->input_window;
 
1199
 
 
1200
  event_mask = 0;
 
1201
  for (dev_list = _gdk_input_devices; dev_list; dev_list = dev_list->next)
 
1202
    {
 
1203
      GdkDevicePrivate *gdkdev = dev_list->data;
 
1204
 
 
1205
      if (!GDK_IS_CORE (gdkdev) &&
 
1206
          gdkdev->info.mode != GDK_MODE_DISABLED &&
 
1207
          iw != NULL)
 
1208
        {
 
1209
          for (l = iw->windows; l != NULL; l = l->next)
 
1210
            {
 
1211
              w = l->data;
 
1212
              if (gdkdev->info.has_cursor || (w->extension_events & GDK_ALL_DEVICES_MASK))
 
1213
                event_mask |= w->extension_events;
 
1214
            }
 
1215
        }
 
1216
    }
 
1217
  
 
1218
  event_mask &= ~GDK_ALL_DEVICES_MASK;
 
1219
  if (event_mask)
 
1220
    event_mask |= 
 
1221
      GDK_PROXIMITY_OUT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK;
 
1222
 
 
1223
  GDK_WINDOW_IMPL_WIN32 (((GdkWindowObject *)impl_window)->impl)->extension_events_mask = event_mask;
1176
1224
}
1177
1225
 
1178
1226
gint
1182
1230
                         GdkWindow    *confine_to,
1183
1231
                         guint32       time)
1184
1232
{
1185
 
  GdkInputWindow *input_window, *new_window;
1186
 
  gboolean need_ungrab;
1187
 
  GdkDevicePrivate *gdkdev;
1188
 
  GList *tmp_list;
1189
 
 
1190
 
  tmp_list = _gdk_input_windows;
1191
 
  new_window = NULL;
1192
 
  need_ungrab = FALSE;
1193
 
 
1194
1233
  GDK_NOTE (INPUT, g_print ("_gdk_input_grab_pointer: %p %d %p\n",
1195
1234
                           GDK_WINDOW_HWND (window),
1196
1235
                           owner_events,
1197
1236
                           (confine_to ? GDK_WINDOW_HWND (confine_to) : 0)));
1198
1237
 
1199
 
  while (tmp_list)
1200
 
    {
1201
 
      input_window = (GdkInputWindow *)tmp_list->data;
1202
 
 
1203
 
      if (input_window->window == window)
1204
 
        new_window = input_window;
1205
 
      else if (input_window->grabbed)
1206
 
        {
1207
 
          input_window->grabbed = FALSE;
1208
 
          need_ungrab = TRUE;
1209
 
        }
1210
 
 
1211
 
      tmp_list = tmp_list->next;
1212
 
    }
1213
 
 
1214
 
  if (new_window)
1215
 
    {
1216
 
      new_window->grabbed = TRUE;
1217
 
      x_grab_window = window;
1218
 
      x_grab_mask = event_mask;
1219
 
      x_grab_owner_events = owner_events;
1220
 
 
1221
 
      /* FIXME: Do we need to handle confine_to and time? */
1222
 
      
1223
 
      tmp_list = _gdk_input_devices;
1224
 
      while (tmp_list)
1225
 
        {
1226
 
          gdkdev = (GdkDevicePrivate *)tmp_list->data;
1227
 
          if (!GDK_IS_CORE (gdkdev) && gdkdev->hctx)
1228
 
            {
1229
 
#if 0         
1230
 
              /* XXX */
1231
 
              gdk_input_common_find_events (window, gdkdev,
1232
 
                                            event_mask,
1233
 
                                            event_classes, &num_classes);
1234
 
              
1235
 
              result = XGrabDevice( GDK_DISPLAY(), gdkdev->xdevice,
1236
 
                                    GDK_WINDOW_XWINDOW (window),
1237
 
                                    owner_events, num_classes, event_classes,
1238
 
                                    GrabModeAsync, GrabModeAsync, time);
1239
 
              
1240
 
              /* FIXME: if failure occurs on something other than the first
1241
 
                 device, things will be badly inconsistent */
1242
 
              if (result != Success)
1243
 
                return result;
1244
 
#endif
1245
 
            }
1246
 
          tmp_list = tmp_list->next;
1247
 
        }
1248
 
    }
1249
 
  else
1250
 
    { 
1251
 
      x_grab_window = NULL;
1252
 
#if 0
1253
 
      tmp_list = _gdk_input_devices;
1254
 
      while (tmp_list)
1255
 
        {
1256
 
          gdkdev = (GdkDevicePrivate *)tmp_list->data;
1257
 
          if (!GDK_IS_CORE (gdkdev) && gdkdev->hctx &&
1258
 
              ((gdkdev->button_state != 0) || need_ungrab))
1259
 
            {
1260
 
#if 0
1261
 
              /* XXX */
1262
 
              XUngrabDevice (gdk_display, gdkdev->xdevice, time);
1263
 
#endif
1264
 
              gdkdev->button_state = 0;
1265
 
            }
1266
 
          
1267
 
          tmp_list = tmp_list->next;
1268
 
        }
1269
 
#endif
1270
 
    }
1271
 
 
1272
1238
  return GDK_GRAB_SUCCESS;
1273
1239
}
1274
1240
 
1275
1241
void 
1276
1242
_gdk_input_ungrab_pointer (guint32 time)
1277
1243
{
1278
 
  GdkInputWindow *input_window;
1279
 
  GdkDevicePrivate *gdkdev;
1280
 
  GList *tmp_list;
1281
1244
 
1282
1245
  GDK_NOTE (INPUT, g_print ("_gdk_input_ungrab_pointer\n"));
1283
1246
 
1284
 
  tmp_list = _gdk_input_windows;
1285
 
  while (tmp_list)
1286
 
    {
1287
 
      input_window = (GdkInputWindow *)tmp_list->data;
1288
 
      if (input_window->grabbed)
1289
 
        break;
1290
 
      tmp_list = tmp_list->next;
1291
 
    }
1292
 
 
1293
 
  if (tmp_list)                 /* we found a grabbed window */
1294
 
    {
1295
 
      input_window->grabbed = FALSE;
1296
 
 
1297
 
      tmp_list = _gdk_input_devices;
1298
 
      while (tmp_list)
1299
 
        {
1300
 
          gdkdev = (GdkDevicePrivate *)tmp_list->data;
1301
 
#if 0
1302
 
          /* XXX */
1303
 
          if (!GDK_IS_CORE (gdkdev) && gdkdev->xdevice)
1304
 
            XUngrabDevice (gdk_display, gdkdev->xdevice, time);
1305
 
#endif
1306
 
          tmp_list = tmp_list->next;
1307
 
        }
1308
 
    }
1309
 
  x_grab_window = NULL;
1310
1247
}
1311
1248
 
1312
1249
gboolean
1344
1281
  else
1345
1282
    {
1346
1283
      GdkDevicePrivate *gdkdev;
1347
 
      GdkInputWindow *input_window;
1348
1284
      
1349
1285
      gdkdev = (GdkDevicePrivate *)device;
1350
1286
      /* For now just use the last known button and axis state of the device.
1359
1295
                       | GDK_BUTTON3_MASK | GDK_BUTTON4_MASK
1360
1296
                       | GDK_BUTTON5_MASK));
1361
1297
        }
1362
 
      input_window = _gdk_input_window_find (window);
1363
 
      g_return_if_fail (input_window != NULL);
1364
1298
      /* For some reason, input_window is sometimes NULL when I use The GIMP 2
1365
1299
       * (bug #141543?). Avoid crashing if debugging is disabled. */
1366
 
      if (axes && gdkdev->last_axis_data && input_window)
1367
 
        gdk_input_translate_coordinates (gdkdev, input_window,
 
1300
      if (axes && gdkdev->last_axis_data)
 
1301
        gdk_input_translate_coordinates (gdkdev, window,
1368
1302
                                         gdkdev->last_axis_data,
1369
1303
                                         axes, NULL, NULL);
1370
1304
    }
1397
1331
void 
1398
1332
_gdk_input_init (GdkDisplay *display)
1399
1333
{
1400
 
  _gdk_input_ignore_core = FALSE;
1401
1334
  _gdk_input_devices = NULL;
1402
1335
 
1403
1336
  _gdk_init_input_core (display);