Exemplo n.º 1
0
static void
gtk_gesture_multi_press_begin (GtkGesture       *gesture,
                               GdkEventSequence *sequence)
{
    GtkGestureMultiPress *multi_press;
    GtkGestureMultiPressPrivate *priv;
    guint n_presses, button = 1;
    GdkEventSequence *current;
    const GdkEvent *event;
    GdkDevice *device;
    gdouble x, y;

    if (!gtk_gesture_handles_sequence (gesture, sequence))
        return;

    multi_press = GTK_GESTURE_MULTI_PRESS (gesture);
    priv = gtk_gesture_multi_press_get_instance_private (multi_press);
    event = gtk_gesture_get_last_event (gesture, sequence);
    current = gtk_gesture_single_get_current_sequence (GTK_GESTURE_SINGLE (gesture));
    device = gdk_event_get_source_device (event);

    if (event->type == GDK_BUTTON_PRESS)
        button = event->button.button;
    else if (event->type == GDK_TOUCH_BEGIN)
        button = 1;
    else
        return;

    /* Reset the gesture if the button number changes mid-recognition */
    if (priv->n_presses > 0 &&
            priv->current_button != button)
        _gtk_gesture_multi_press_stop (multi_press);

    /* Reset also if the device changed */
    if (priv->current_device && priv->current_device != device)
        _gtk_gesture_multi_press_stop (multi_press);

    priv->current_device = device;
    priv->current_button = button;
    _gtk_gesture_multi_press_update_timeout (multi_press);
    gtk_gesture_get_point (gesture, current, &x, &y);

    if (!_gtk_gesture_multi_press_check_within_threshold (multi_press, x, y))
        _gtk_gesture_multi_press_stop (multi_press);

    /* Increment later the real counter, just if the gesture is
     * reset on the pressed handler */
    n_presses = priv->n_release = priv->n_presses + 1;

    g_signal_emit (gesture, signals[PRESSED], 0, n_presses, x, y);

    if (priv->n_presses == 0)
    {
        priv->initial_press_x = x;
        priv->initial_press_y = y;
    }

    priv->n_presses++;
}
Exemplo n.º 2
0
void PageClientImpl::doneWithTouchEvent(const NativeWebTouchEvent& event, bool wasEventHandled)
{
    if (wasEventHandled)
        return;

#if HAVE(GTK_GESTURES)
    GestureController& gestureController = webkitWebViewBaseGestureController(WEBKIT_WEB_VIEW_BASE(m_viewWidget));
    if (gestureController.handleEvent(event.nativeEvent()))
        return;
#endif

    // Emulate pointer events if unhandled.
    const GdkEvent* touchEvent = event.nativeEvent();

    if (!touchEvent->touch.emulating_pointer)
        return;

    GUniquePtr<GdkEvent> pointerEvent;

    if (touchEvent->type == GDK_TOUCH_UPDATE) {
        pointerEvent.reset(gdk_event_new(GDK_MOTION_NOTIFY));
        pointerEvent->motion.time = touchEvent->touch.time;
        pointerEvent->motion.x = touchEvent->touch.x;
        pointerEvent->motion.y = touchEvent->touch.y;
        pointerEvent->motion.x_root = touchEvent->touch.x_root;
        pointerEvent->motion.y_root = touchEvent->touch.y_root;
        pointerEvent->motion.state = touchEvent->touch.state | GDK_BUTTON1_MASK;
    } else {
        switch (touchEvent->type) {
        case GDK_TOUCH_END:
            pointerEvent.reset(gdk_event_new(GDK_BUTTON_RELEASE));
            pointerEvent->button.state = touchEvent->touch.state | GDK_BUTTON1_MASK;
            break;
        case GDK_TOUCH_BEGIN:
            pointerEvent.reset(gdk_event_new(GDK_BUTTON_PRESS));
            break;
        default:
            ASSERT_NOT_REACHED();
        }

        pointerEvent->button.button = 1;
        pointerEvent->button.time = touchEvent->touch.time;
        pointerEvent->button.x = touchEvent->touch.x;
        pointerEvent->button.y = touchEvent->touch.y;
        pointerEvent->button.x_root = touchEvent->touch.x_root;
        pointerEvent->button.y_root = touchEvent->touch.y_root;
    }

    gdk_event_set_device(pointerEvent.get(), gdk_event_get_device(touchEvent));
    gdk_event_set_source_device(pointerEvent.get(), gdk_event_get_source_device(touchEvent));
    pointerEvent->any.window = GDK_WINDOW(g_object_ref(touchEvent->any.window));
    pointerEvent->any.send_event = TRUE;

    gtk_widget_event(m_viewWidget, pointerEvent.get());
}
Exemplo n.º 3
0
gboolean on_buttonpress (GtkWidget *win, 
			 GdkEventButton *ev,
			 gpointer user_data)
{
  GromitData *data = (GromitData *) user_data;
  gdouble pressure = 0.5;

  /* get the data for this device */
  GdkDevice *master = ev->device;
  GromitDeviceData *masterdata =
    g_hash_table_lookup(data->devdatatable, master);
  GdkDevice *slave =
    gdk_event_get_source_device ((GdkEvent *) ev);
  GromitDeviceData *slavedata =
    g_hash_table_lookup(data->devdatatable, slave);

  if(data->debug)
    g_printerr("DEBUG: Device '%s': Button %i Down at (x,y)=(%.2f : %.2f)\n", 
	       gdk_device_get_name(slave), ev->button, ev->x, ev->y);

  if (!masterdata->is_grabbed)
    return FALSE;

  /* See GdkModifierType. Am I fixing a Gtk misbehaviour???  */
  ev->state |= 1 << (ev->button + 7);

  if (ev->state != masterdata->state ||
      ev->state != slavedata->state ||
      masterdata->lastslave != slave)
    select_tool (data, master, slave, ev->state);

  slavedata->lastx = ev->x;
  slavedata->lasty = ev->y;
  slavedata->motion_time = ev->time;

  snap_undo_state (data);
  if (gdk_device_get_source(slave) == GDK_SOURCE_MOUSE)
    {
      data->maxwidth = slavedata->cur_context->width;
    }
  else
    {
      gdk_event_get_axis ((GdkEvent *) ev, GDK_AXIS_PRESSURE, &pressure);
      data->maxwidth = (CLAMP (pressure + line_thickener, 0, 1) *
                        (double) (slavedata->cur_context->width -
				  slavedata->cur_context->minwidth) +
			slavedata->cur_context->minwidth);
    }
  if (ev->button <= 5)
    draw_line (data, slave, ev->x, ev->y, ev->x, ev->y);

  coord_list_prepend (data, slave, ev->x, ev->y, data->maxwidth);

  return TRUE;
}
Exemplo n.º 4
0
static gboolean
tooltips_enabled (GdkEvent *event)
{
  GdkDevice *source_device;
  GdkInputSource source;

  source_device = gdk_event_get_source_device (event);

  if (!source_device)
    return FALSE;

  source = gdk_device_get_source (source_device);

  if (source != GDK_SOURCE_TOUCHSCREEN)
    return TRUE;

  return FALSE;
}
Exemplo n.º 5
0
gboolean on_buttonrelease (GtkWidget *win, 
			   GdkEventButton *ev, 
			   gpointer user_data)
{
  GromitData *data = (GromitData *) user_data;

  /* get the data for this device */
  GdkDevice *master = ev->device;
  GromitDeviceData *masterdata =
    g_hash_table_lookup(data->devdatatable, master);
  GdkDevice *slave =
    gdk_event_get_source_device ((GdkEvent *) ev);
  GromitDeviceData *slavedata =
    g_hash_table_lookup(data->devdatatable, slave);

  if(data->debug)
    g_printerr("DEBUG: Device '%s': Button %i Up at (x,y)=(%.2f : %.2f)\n", 
	       gdk_device_get_name(slave), ev->button, ev->x, ev->y);

  gfloat direction = 0;
  gint width = 0;
  if(slavedata->cur_context)
    width = slavedata->cur_context->arrowsize *
      slavedata->cur_context->width / 2;

  if ((ev->x != slavedata->lastx) ||
      (ev->y != slavedata->lasty))
    on_motion(win, (GdkEventMotion *) ev, user_data);


  if (!masterdata->is_grabbed)
    return FALSE;

  if (slavedata->cur_context->arrowsize != 0 &&
      coord_list_get_arrow_param (data, slave, width * 3,
				  &width, &direction))
    draw_arrow (data, slave, ev->x, ev->y, width, direction);

  coord_list_free (data, slave);

  return TRUE;
}
static gboolean
photos_preview_nav_buttons_motion_notify (PhotosPreviewNavButtons *self, GdkEventMotion *event)
{
  GdkDevice *device;
  GdkInputSource input_source;

  if (self->motion_id != 0)
    return FALSE;

  device = gdk_event_get_source_device ((GdkEvent *) event);
  input_source = gdk_device_get_source (device);
  if (input_source == GDK_SOURCE_TOUCHSCREEN)
    return FALSE;

  self->motion_id = g_idle_add_full (G_PRIORITY_DEFAULT,
                                     (GSourceFunc) photos_preview_nav_buttons_motion_notify_timeout,
                                     g_object_ref (self),
                                     g_object_unref);
  return FALSE;
}
static gboolean
on_button_press_event(GtkWidget      *widget,
                      GdkEventButton *event,
                      CalibArea      *area)
{
    gboolean success;

    if (area->success)
        return FALSE;

    /* Check matching device ID if a device ID was provided */
    if (area->device_id > -1) {
        GdkDevice *device;

        device = gdk_event_get_source_device ((GdkEvent *) event);
        if (device != NULL && gdk_x11_device_get_id (device) != area->device_id)
	    return FALSE;
    }

    /* Handle click */
    area->time_elapsed = 0;
    success = add_click(&area->calibrator, (int)event->x_root, (int)event->y_root);

    if (!success && area->calibrator.num_clicks == 0)
        draw_message(area, N_("Mis-click detected, restarting..."));
    else
        draw_message(area, NULL);

    /* Are we done yet? */
    if (area->calibrator.num_clicks >= 4)
    {
        set_calibration_status (area);
        return FALSE;
    }

    /* Force a redraw */
    redraw(area);

    return FALSE;
}
/* This shots when the pointer is moving. */
G_MODULE_EXPORT gboolean
on_motion_notify   (GtkWidget       *win,
                    GdkEventMotion  *ev,
                    gpointer         user_data)
{
  AnnotateData *data = (AnnotateData *) user_data;
  GdkDevice *master = gdk_event_get_device ( (GdkEvent *) ev);
  GdkDevice *slave = gdk_event_get_source_device ( (GdkEvent *) ev);
  
  /* Get the data for this device. */
  AnnotateDeviceData *masterdata= g_hash_table_lookup (data->devdatatable, master);
  AnnotateDeviceData *slavedata = g_hash_table_lookup (data->devdatatable, slave);

   if (data->cur_context == data->default_filler)
    {
      return FALSE;
    }
    
  if (ev->state != masterdata->state ||
      ev->state != slavedata->state  ||
      masterdata->lastslave != slave)
    {
       annotate_select_tool (data, master, slave, ev->state);
    }

  gdouble selected_width = 0.0;
  gdouble pressure = 1.0; 

  if (!data->is_grabbed)
    {
      return FALSE;
    }

  if (!ev)
    {
      g_printerr ("Device '%s': Invalid event; I ungrab all\n",
                  gdk_device_get_name (master));
      annotate_release_grab ();
      return FALSE;
    }

  if (data->debug)
    {
      g_printerr ("Device '%s': Move at (x,y)= (%f : %f)\n",
                  gdk_device_get_name (master),
                  ev->x,
                  ev->y);
    }
  
#ifdef _WIN32
  if (inside_bar_window (ev->x_root, ev->y_root))
    {

      if (data->debug)
        {
          g_printerr ("Device '%s': Move on the bar then ungrab\n",
                       gdk_device_get_name (master));
        }

      /* The point is inside the ardesia bar then ungrab. */
      annotate_release_grab ();
      return FALSE;
    }
#endif

  annotate_unhide_cursor ();
  
  /* Only the first 5 buttons allowed. */
  if(!(ev->state & (GDK_BUTTON1_MASK|
                    GDK_BUTTON2_MASK|
                    GDK_BUTTON3_MASK|
                    GDK_BUTTON4_MASK|
                    GDK_BUTTON5_MASK)))
    {
      return TRUE;
    }

  initialize_annotation_cairo_context (data);

  annotate_configure_pen_options (data);
  
  if (data->cur_context->type != ANNOTATE_ERASER)
    {
      pressure = get_pressure ( (GdkEvent *) ev);

      if (pressure <= 0)
        {
          return FALSE;
        }

      /* If the point is already selected and higher pressure then print else jump it. */
      if (masterdata->coord_list)
        {
          AnnotatePoint *last_point = (AnnotatePoint *) g_slist_nth_data (masterdata->coord_list, 0);
          gdouble tollerance = annotate_get_thickness ();

          if (get_distance (last_point->x, last_point->y, ev->x, ev->y)<tollerance)
            {
              /* Seems that you are uprising the pen. */
              if (pressure <= last_point->pressure)
                {
                  /* Jump the point you are uprising the hand. */
                  return FALSE;
                }
              else // pressure >= last_point->pressure
                {
                  /* Seems that you are pressing the pen more. */
                  annotate_modify_color (masterdata, data, pressure);
                  annotate_draw_line (masterdata, ev->x, ev->y, TRUE);
                  /* Store the new pressure without allocate a new coordinate. */
                  last_point->pressure = pressure;
                  return TRUE;
                }
            }
          annotate_modify_color (masterdata, data, pressure);
        }
    }
    
  annotate_draw_line (masterdata, ev->x, ev->y, TRUE);
  annotate_coord_list_prepend (masterdata, ev->x, ev->y, selected_width, pressure);

  return TRUE;
}
Exemplo n.º 9
0
/**
 * clutter_gdk_handle_event:
 * @event: a #GdkEvent
 *
 * This function processes a single GDK event; it can be used to hook
 * into external event processing
 *
 * Return value: #GdkFilterReturn. %GDK_FILTER_REMOVE indicates that
 *  Clutter has internally handled the event and the caller should do
 *  no further processing. %GDK_FILTER_CONTINUE indicates that Clutter
 *  is either not interested in the event, or has used the event to
 *  update internal state without taking any exclusive action.
 *  %GDK_FILTER_TRANSLATE will not occur.
 *
 */
GdkFilterReturn
clutter_gdk_handle_event (GdkEvent *gdk_event)
{
  ClutterDeviceManager *device_manager;
  ClutterBackendGdk *backend_gdk;
  ClutterBackend *backend;
  ClutterStage *stage = NULL;
  ClutterEvent *event = NULL;
  gint spin = 0;
  GdkFilterReturn result = GDK_FILTER_CONTINUE;
  ClutterInputDevice *device, *source_device;
  GdkDevice *gdk_device;

  backend = clutter_get_default_backend ();
  if (!CLUTTER_IS_BACKEND_GDK (backend))
    return GDK_FILTER_CONTINUE;

  if (gdk_event->any.window == NULL)
    return GDK_FILTER_CONTINUE;

  device_manager = clutter_device_manager_get_default ();
  if (G_UNLIKELY (device_manager == NULL))
    return GDK_FILTER_CONTINUE;

  backend_gdk = CLUTTER_BACKEND_GDK (backend);
  stage = clutter_gdk_get_stage_from_window (gdk_event->any.window);

  gdk_device = gdk_event_get_device (gdk_event);
  if (gdk_device != NULL)
    device = _clutter_device_manager_gdk_lookup_device (device_manager,
                                                        gdk_device);
  else
    device = NULL;

  gdk_device = gdk_event_get_source_device (gdk_event);
  if (gdk_device != NULL)
    source_device = _clutter_device_manager_gdk_lookup_device (device_manager,
                                                               gdk_device);
  else
    source_device = NULL;

  if (stage == NULL)
    return GDK_FILTER_CONTINUE;

  _clutter_threads_acquire_lock ();

  switch (gdk_event->type)
    {
    case GDK_DELETE:
      event = clutter_event_new (CLUTTER_DELETE);
      break;

    case GDK_DESTROY:
      event = clutter_event_new (CLUTTER_DESTROY_NOTIFY);
      break;

    case GDK_EXPOSE:
      {
        ClutterPaintVolume clip;
        ClutterVertex origin;

        CLUTTER_NOTE (EVENT, "Expose for stage '%s' [%p] { %d, %d - %d x %d }",
                      _clutter_actor_get_debug_name (CLUTTER_ACTOR (stage)),
                      stage,
                      gdk_event->expose.area.x,
                      gdk_event->expose.area.y,
                      gdk_event->expose.area.width,
                      gdk_event->expose.area.height);

        origin.x = gdk_event->expose.area.x;
        origin.y = gdk_event->expose.area.y;
        origin.z = 0;

        _clutter_paint_volume_init_static (&clip, CLUTTER_ACTOR (stage));

        clutter_paint_volume_set_origin (&clip, &origin);
        clutter_paint_volume_set_width (&clip, gdk_event->expose.area.width);
        clutter_paint_volume_set_height (&clip, gdk_event->expose.area.height);

        _clutter_actor_queue_redraw_with_clip (CLUTTER_ACTOR (stage), 0, &clip);

        clutter_paint_volume_free (&clip);
      }
      break;

    case GDK_DAMAGE:
      /* This is handled by cogl */
      break;

    case GDK_MOTION_NOTIFY:
      event = clutter_event_new (CLUTTER_MOTION);
      event->motion.time = gdk_event->motion.time;
      event->motion.x = gdk_event->motion.x;
      event->motion.y = gdk_event->motion.y;
      event->motion.axes = NULL;
      /* It's all X in the end, right? */
      event->motion.modifier_state = gdk_event->motion.state;
      clutter_event_set_device (event, device);
      clutter_event_set_source_device (event, source_device);
      CLUTTER_NOTE (EVENT, "Motion notifiy [%.2f, %.2f]",
                    event->motion.x,
                    event->motion.y);
      break;

    case GDK_BUTTON_PRESS:
    case GDK_BUTTON_RELEASE:
      event = clutter_event_new (gdk_event->type == GDK_BUTTON_PRESS ?
                                 CLUTTER_BUTTON_PRESS :
                                 CLUTTER_BUTTON_RELEASE);
      event->button.time = gdk_event->button.time;
      event->button.x = gdk_event->button.x;
      event->button.y = gdk_event->button.y;
      event->button.axes = NULL;
      event->button.modifier_state = gdk_event->button.state;
      event->button.button = gdk_event->button.button;
      event->button.click_count = 1;
      clutter_event_set_device (event, device);
      clutter_event_set_source_device (event, source_device);
      CLUTTER_NOTE (EVENT, "Button %d %s [%.2f, %.2f]",
                    event->button.button,
                    event->type == CLUTTER_BUTTON_PRESS ? "press" : "release",
                    event->button.x,
                    event->button.y);
      break;

    case GDK_2BUTTON_PRESS:
    case GDK_3BUTTON_PRESS:
      /* these are handled by clutter-main.c updating click_count */
      break;

    case GDK_KEY_PRESS:
    case GDK_KEY_RELEASE:
      event = clutter_event_new (gdk_event->type == GDK_KEY_PRESS ?
                                 CLUTTER_KEY_PRESS :
                                 CLUTTER_KEY_RELEASE);
      event->key.time = gdk_event->key.time;
      event->key.modifier_state = gdk_event->key.state;
      event->key.keyval = gdk_event->key.keyval;
      event->key.hardware_keycode = gdk_event->key.hardware_keycode;
      event->key.unicode_value = g_utf8_get_char (gdk_event->key.string);
      clutter_event_set_device (event, device);
      clutter_event_set_source_device (event, source_device);
      CLUTTER_NOTE (EVENT, "Key %d %s",
                    event->key.keyval,
                    event->type == CLUTTER_KEY_PRESS ? "press" : "release");
      break;

    case GDK_ENTER_NOTIFY:
    case GDK_LEAVE_NOTIFY:
      event = clutter_event_new (gdk_event->type == GDK_ENTER_NOTIFY ?
                                 CLUTTER_ENTER :
                                 CLUTTER_LEAVE);
      event->crossing.source = CLUTTER_ACTOR (stage);
      event->crossing.time = gdk_event_get_time (gdk_event);
      event->crossing.x = gdk_event->crossing.x;
      event->crossing.y = gdk_event->crossing.y;

      /* XXX: no better fallback here? */
      clutter_event_set_device (event, device);
      clutter_event_set_source_device (event, source_device);
      if (gdk_event->type == GDK_ENTER_NOTIFY)
        _clutter_input_device_set_stage (clutter_event_get_device (event), stage);
      else
        _clutter_input_device_set_stage (clutter_event_get_device (event), NULL);
      CLUTTER_NOTE (EVENT, "Crossing %s [%.2f, %.2f]",
                    event->type == CLUTTER_ENTER ? "enter" : "leave",
                    event->crossing.x,
                    event->crossing.y);
      break;

    case GDK_FOCUS_CHANGE:
      if (gdk_event->focus_change.in)
        _clutter_stage_update_state (stage, 0, CLUTTER_STAGE_STATE_ACTIVATED);
      else
        _clutter_stage_update_state (stage, CLUTTER_STAGE_STATE_ACTIVATED, 0);
      break;

    case GDK_CONFIGURE:
      {
        gfloat w, h;

        clutter_actor_get_size (CLUTTER_ACTOR (stage), &w, &h);

        if (w != gdk_event->configure.width ||
            h != gdk_event->configure.height)
          {
            clutter_actor_set_size (CLUTTER_ACTOR (stage),
                                    gdk_event->configure.width,
                                    gdk_event->configure.height);
          }
      }
      break;

    case GDK_SCROLL:
      event = clutter_event_new (CLUTTER_SCROLL);
      event->scroll.time = gdk_event->scroll.time;
      event->scroll.x = gdk_event->scroll.x;
      event->scroll.y = gdk_event->scroll.y;
      event->scroll.modifier_state = gdk_event->scroll.state;
      event->scroll.axes = NULL;
      /* XXX: must keep ClutterScrollDirection compatible with GdkScrollDirection */
      event->scroll.direction = (ClutterScrollDirection) gdk_event->scroll.direction;
      clutter_event_set_device (event, device);
      clutter_event_set_source_device (event, source_device);
      clutter_event_set_scroll_delta (event,
                                      gdk_event->scroll.delta_x,
                                      gdk_event->scroll.delta_y);
      break;

    case GDK_WINDOW_STATE:
      if (gdk_event->window_state.changed_mask & GDK_WINDOW_STATE_FULLSCREEN)
        {
          gboolean is_fullscreen;

          is_fullscreen = (gdk_event->window_state.new_window_state & GDK_WINDOW_STATE_FULLSCREEN) != 0;
          if (is_fullscreen)
            _clutter_stage_update_state (stage, 0, CLUTTER_STAGE_STATE_FULLSCREEN);
          else
            _clutter_stage_update_state (stage, CLUTTER_STAGE_STATE_FULLSCREEN, 0);
        }
      break;

    case GDK_SETTING:
      _clutter_backend_gdk_update_setting (backend_gdk, gdk_event->setting.name);
      break;

    default:
      break;
    }

  if (event != NULL)
    {
      event->any.stage = stage;

      if (gdk_event->any.send_event)
	event->any.flags = CLUTTER_EVENT_FLAG_SYNTHETIC;

      _clutter_event_push (event, FALSE);

      spin = 1;

      CLUTTER_NOTE (EVENT, "Translated one event from Gdk");

      /* handle also synthetic enter/leave events */
      if (event->type == CLUTTER_MOTION)
	spin += 2;

      while (spin > 0 && (event = clutter_event_get ()))
	{
	  /* forward the event into clutter for emission etc. */
	  clutter_do_event (event);
	  clutter_event_free (event);
	  --spin;
	}

      result = GDK_FILTER_REMOVE;
    }

  _clutter_threads_release_lock ();

  return result;
}
Exemplo n.º 10
0
static gboolean
gtk_gesture_single_handle_event (GtkEventController *controller,
                                 const GdkEvent     *event)
{
  GdkEventSequence *sequence = NULL;
  GtkGestureSinglePrivate *priv;
  GdkDevice *source_device;
  GdkInputSource source;
  guint button = 0, i;
  gboolean retval, test_touchscreen = FALSE;

  source_device = gdk_event_get_source_device (event);

  if (!source_device)
    return FALSE;

  priv = gtk_gesture_single_get_instance_private (GTK_GESTURE_SINGLE (controller));
  source = gdk_device_get_source (source_device);

  if (source != GDK_SOURCE_TOUCHSCREEN)
    test_touchscreen = gtk_simulate_touchscreen ();

  switch (event->type)
    {
    case GDK_TOUCH_BEGIN:
    case GDK_TOUCH_END:
    case GDK_TOUCH_UPDATE:
      if (priv->exclusive && !event->touch.emulating_pointer)
        return FALSE;

      sequence = event->touch.sequence;
      button = 1;
      break;
    case GDK_BUTTON_PRESS:
    case GDK_BUTTON_RELEASE:
      if (priv->touch_only && !test_touchscreen && source != GDK_SOURCE_TOUCHSCREEN)
        return FALSE;

      button = event->button.button;
      break;
    case GDK_MOTION_NOTIFY:
      if (!gtk_gesture_handles_sequence (GTK_GESTURE (controller), sequence))
        return FALSE;
      if (priv->touch_only && !test_touchscreen && source != GDK_SOURCE_TOUCHSCREEN)
        return FALSE;

      if (priv->current_button > 0 && priv->current_button <= 5 &&
          (event->motion.state & (GDK_BUTTON1_MASK << (priv->current_button - 1))))
        button = priv->current_button;
      else if (priv->current_button == 0)
        {
          /* No current button, find out from the mask */
          for (i = 0; i < 3; i++)
            {
              if ((event->motion.state & (GDK_BUTTON1_MASK << i)) == 0)
                continue;
              button = i + 1;
              break;
            }
        }

      break;
    case GDK_TOUCH_CANCEL:
    case GDK_GRAB_BROKEN:
      return GTK_EVENT_CONTROLLER_CLASS (gtk_gesture_single_parent_class)->handle_event (controller,
                                                                                         event);
      break;
    default:
      return FALSE;
    }

  if (button == 0 ||
      (priv->button != 0 && priv->button != button) ||
      (priv->current_button != 0 && priv->current_button != button))
    {
      if (gtk_gesture_is_active (GTK_GESTURE (controller)))
        gtk_event_controller_reset (controller);
      return FALSE;
    }

  if (event->type == GDK_BUTTON_PRESS || event->type == GDK_TOUCH_BEGIN ||
      event->type == GDK_MOTION_NOTIFY || event->type == GDK_TOUCH_UPDATE)
    {
      if (!gtk_gesture_is_active (GTK_GESTURE (controller)))
        priv->current_sequence = sequence;

      priv->current_button = button;
    }

  retval = GTK_EVENT_CONTROLLER_CLASS (gtk_gesture_single_parent_class)->handle_event (controller, event);

  if (sequence == priv->current_sequence &&
      (event->type == GDK_BUTTON_RELEASE || event->type == GDK_TOUCH_END))
    priv->current_button = 0;
  else if (priv->current_sequence == sequence &&
           !gtk_gesture_handles_sequence (GTK_GESTURE (controller), sequence))
    {
      if (button == priv->current_button && event->type == GDK_BUTTON_PRESS)
        priv->current_button = 0;
      else if (sequence == priv->current_sequence && event->type == GDK_TOUCH_BEGIN)
        priv->current_sequence = NULL;
    }

  return retval;
}
Exemplo n.º 11
0
gboolean on_motion (GtkWidget *win,
		    GdkEventMotion *ev,
		    gpointer user_data)
{
  GromitData *data = (GromitData *) user_data;
  GdkTimeCoord **coords = NULL;
  gint nevents;
  int i;
  gdouble pressure = 0.5;

  /* get the data for this device */
  GdkDevice *master = ev->device;
  GromitDeviceData *masterdata =
    g_hash_table_lookup(data->devdatatable, master);

  if (!masterdata->is_grabbed)
    return FALSE;

  GdkDevice *slave =
    gdk_event_get_source_device ((GdkEvent *) ev);
  GromitDeviceData *slavedata =
    g_hash_table_lookup(data->devdatatable, slave);

  if (ev->state != masterdata->state ||
      ev->state != slavedata->state ||
      masterdata->lastslave != slave)
    select_tool (data, master, slave, ev->state);

  if(!(ev->state & (GDK_BUTTON1_MASK|
                    GDK_BUTTON2_MASK|
                    GDK_BUTTON3_MASK|
                    GDK_BUTTON4_MASK|
                    GDK_BUTTON5_MASK)))
    return TRUE;

  gdk_device_get_history (slave, ev->window,
                          slavedata->motion_time, ev->time,
                          &coords, &nevents);

  if(!data->xinerama && nevents > 0)
    {
      for (i=0; i < nevents; i++)
        {
          gdouble x, y;

          gdk_device_get_axis (slave, coords[i]->axes,
                               GDK_AXIS_PRESSURE, &pressure);
          if (pressure > 0)
            {
              if (gdk_device_get_source(slave) == GDK_SOURCE_MOUSE)
                data->maxwidth = slavedata->cur_context->width;
              else
		data->maxwidth = (CLAMP (pressure + line_thickener, 0, 1) *
				  (double) (slavedata->cur_context->width -
					    slavedata->cur_context->minwidth) +
				  slavedata->cur_context->minwidth);

              gdk_device_get_axis(slave, coords[i]->axes,
                                  GDK_AXIS_X, &x);
              gdk_device_get_axis(slave, coords[i]->axes,
                                  GDK_AXIS_Y, &y);

	      draw_line (data, slave, slavedata->lastx, slavedata->lasty, x, y);

              coord_list_prepend (data, slave, x, y, data->maxwidth);
              slavedata->lastx = x;
              slavedata->lasty = y;
            }
        }

      slavedata->motion_time = coords[nevents-1]->time;
      g_free (coords);
    }

  /* always paint to the current event coordinate. */
  gdk_event_get_axis ((GdkEvent *) ev, GDK_AXIS_PRESSURE, &pressure);

  if (pressure > 0)
    {
      if (gdk_device_get_source(slave) == GDK_SOURCE_MOUSE)
	data->maxwidth = slavedata->cur_context->width;
      else
	data->maxwidth = (CLAMP (pressure + line_thickener, 0, 1) *
			  (double) (slavedata->cur_context->width -
				    slavedata->cur_context->minwidth) +
			  slavedata->cur_context->minwidth);

      if(slavedata->motion_time > 0)
	{
	  draw_line (data, slave, slavedata->lastx, slavedata->lasty, ev->x, ev->y);
	  coord_list_prepend (data, slave, ev->x, ev->y, data->maxwidth);
	}
    }

  slavedata->lastx = ev->x;
  slavedata->lasty = ev->y;
  slavedata->motion_time = ev->time;

  return TRUE;
}