Esempio n. 1
0
void
_gdk_wayland_display_convert_selection (GdkDisplay *display,
                                        GdkWindow  *requestor,
                                        GdkAtom     selection,
                                        GdkAtom     target,
                                        guint32     time)
{
  GdkWaylandSelection *wayland_selection = gdk_wayland_display_get_selection (display);
  SelectionBuffer *buffer_data;

  if (!wayland_selection->offer)
    {
      GdkEvent *event;

      event = gdk_event_new (GDK_SELECTION_NOTIFY);
      event->selection.window = g_object_ref (requestor);
      event->selection.send_event = FALSE;
      event->selection.selection = selection;
      event->selection.target = target;
      event->selection.property = GDK_NONE;
      event->selection.time = GDK_CURRENT_TIME;
      event->selection.requestor = g_object_ref (requestor);

      gdk_event_put (event);
      gdk_event_free (event);
      return;
    }

  if (target != gdk_atom_intern_static_string ("TARGETS"))
    wl_data_offer_accept (wayland_selection->offer,
                          _gdk_wayland_display_get_serial (GDK_WAYLAND_DISPLAY (display)),
                          gdk_atom_name (target));

  buffer_data = g_hash_table_lookup (wayland_selection->selection_buffers,
                                     target);

  if (buffer_data)
    selection_buffer_add_requestor (buffer_data, requestor);
  else
    {
      GInputStream *stream = NULL;
      int pipe_fd[2], natoms = 0;
      GdkAtom *targets = NULL;

      if (target == gdk_atom_intern_static_string ("TARGETS"))
        {
          gint i = 0;
          GList *l;

          natoms = g_list_length (wayland_selection->targets);
          targets = g_new0 (GdkAtom, natoms);

          for (l = wayland_selection->targets; l; l = l->next)
            targets[i++] = l->data;
        }
      else
        {
          g_unix_open_pipe (pipe_fd, FD_CLOEXEC, NULL);
          wl_data_offer_receive (wayland_selection->offer,
                                 gdk_atom_name (target),
                                 pipe_fd[1]);
          stream = g_unix_input_stream_new (pipe_fd[0], TRUE);
          close (pipe_fd[1]);
        }

      buffer_data = selection_buffer_new (stream, selection, target);
      selection_buffer_add_requestor (buffer_data, requestor);

      if (stream)
        g_object_unref (stream);

      if (targets)
        {
          /* Store directly the local atoms */
          selection_buffer_append_data (buffer_data, targets, natoms * sizeof (GdkAtom));
          g_free (targets);
        }

      g_hash_table_insert (wayland_selection->selection_buffers,
                           GDK_ATOM_TO_POINTER (target),
                           buffer_data);
    }

  if (!buffer_data->stream)
    selection_buffer_notify (buffer_data);
}
Esempio n. 2
0
/* We only care about focus events that indicate that _this_
 * window (not a ancestor or child) got or lost the focus
 */
void
_gdk_device_manager_core_handle_focus (GdkWindow *window,
                                       Window     original,
                                       GdkDevice *device,
                                       GdkDevice *source_device,
                                       gboolean   focus_in,
                                       int        detail,
                                       int        mode)
{
  GdkToplevelX11 *toplevel;
  GdkX11Screen *x11_screen;
  gboolean had_focus;

  g_return_if_fail (GDK_IS_WINDOW (window));
  g_return_if_fail (GDK_IS_DEVICE (device));
  g_return_if_fail (source_device == NULL || GDK_IS_DEVICE (source_device));

  GDK_NOTE (EVENTS,
            g_message ("focus out:\t\twindow: %ld, detail: %s, mode: %s",
                       GDK_WINDOW_XID (window),
                       notify_details[detail],
                       notify_modes[mode]));

  toplevel = _gdk_x11_window_get_toplevel (window);

  if (!toplevel)
    return;

  if (toplevel->focus_window == original)
    return;

  had_focus = HAS_FOCUS (toplevel);
  x11_screen = GDK_X11_SCREEN (gdk_window_get_screen (window));

  switch (detail)
    {
    case NotifyAncestor:
    case NotifyVirtual:
      /* When the focus moves from an ancestor of the window to
       * the window or a descendent of the window, *and* the
       * pointer is inside the window, then we were previously
       * receiving keystroke events in the has_pointer_focus
       * case and are now receiving them in the
       * has_focus_window case.
       */
      if (toplevel->has_pointer &&
          !x11_screen->wmspec_check_window &&
          mode != NotifyGrab &&
#ifdef XINPUT_2
	  mode != XINotifyPassiveGrab &&
	  mode != XINotifyPassiveUngrab &&
#endif /* XINPUT_2 */
          mode != NotifyUngrab)
        toplevel->has_pointer_focus = (focus_in) ? FALSE : TRUE;

      /* fall through */
    case NotifyNonlinear:
    case NotifyNonlinearVirtual:
      if (mode != NotifyGrab &&
#ifdef XINPUT_2
	  mode != XINotifyPassiveGrab &&
	  mode != XINotifyPassiveUngrab &&
#endif /* XINPUT_2 */
          mode != NotifyUngrab)
        toplevel->has_focus_window = (focus_in) ? TRUE : FALSE;
      /* We pretend that the focus moves to the grab
       * window, so we pay attention to NotifyGrab
       * NotifyUngrab, and ignore NotifyWhileGrabbed
       */
      if (mode != NotifyWhileGrabbed)
        toplevel->has_focus = (focus_in) ? TRUE : FALSE;
      break;
    case NotifyPointer:
      /* The X server sends NotifyPointer/NotifyGrab,
       * but the pointer focus is ignored while a
       * grab is in effect
       */
      if (!x11_screen->wmspec_check_window &&
          mode != NotifyGrab &&
#ifdef XINPUT_2
	  mode != XINotifyPassiveGrab &&
	  mode != XINotifyPassiveUngrab &&
#endif /* XINPUT_2 */
          mode != NotifyUngrab)
        toplevel->has_pointer_focus = (focus_in) ? TRUE : FALSE;
      break;
    case NotifyInferior:
    case NotifyPointerRoot:
    case NotifyDetailNone:
    default:
      break;
    }

  if (HAS_FOCUS (toplevel) != had_focus)
    {
      GdkEvent *event;

      event = gdk_event_new (GDK_FOCUS_CHANGE);
      event->focus_change.window = g_object_ref (window);
      event->focus_change.send_event = FALSE;
      event->focus_change.in = focus_in;
      gdk_event_set_device (event, device);
      if (source_device)
        gdk_event_set_source_device (event, source_device);

      gdk_event_put (event);
      gdk_event_free (event);
    }
}
Esempio n. 3
0
/* dir is either ZOOM_IN, ZOOM_OUT or ZOOM_FULL which are defined in globals.h */
void
a_zoom(GschemToplevel *w_current, GschemPageView *page_view, int dir, int selected_from)
{
  g_return_if_fail (page_view != NULL);

  GschemPageGeometry *geometry = gschem_page_view_get_page_geometry (page_view);
  g_return_if_fail (geometry != NULL);

  double world_pan_center_x,world_pan_center_y,relativ_zoom_factor = - 1;
  int start_x, start_y;
  double top, bottom, right, left;


  /* NB: w_current->zoom_gain is a percentage increase */
  switch(dir) {
  case(ZOOM_IN):
    relativ_zoom_factor = (100.0 + w_current->zoom_gain) / 100.0;
    break;

  case(ZOOM_OUT):
    relativ_zoom_factor = 100.0 / (100.0 + w_current->zoom_gain);
    break;

  case(ZOOM_FULL):
    /* indicate the zoom full with a negative zoomfactor */
    relativ_zoom_factor = -1;
    break;
  }

  /* calc center: either "mouse_to_world" or center=center or a
     virtual center if warp_cursor is disabled */
  if (w_current->zoom_with_pan == TRUE && selected_from == HOTKEY) {
    if (!x_event_get_pointer_position(w_current, FALSE,
				      &start_x, &start_y))
      return;
    if ( w_current->warp_cursor ) {
      world_pan_center_x = start_x;
      world_pan_center_y = start_y;
    } else {
      left = ((geometry->viewport_left - start_x) * (1/relativ_zoom_factor) + start_x);
      right = ((geometry->viewport_right - start_x) * (1/relativ_zoom_factor) + start_x);
      top = ((geometry->viewport_top - start_y) * (1/relativ_zoom_factor) + start_y);
      bottom = ((geometry->viewport_bottom - start_y) * (1/relativ_zoom_factor) + start_y);
      world_pan_center_x = (right + left) / 2;
      world_pan_center_y = (top + bottom) / 2;
    }
  } else {
    world_pan_center_x = (double) (geometry->viewport_left + geometry->viewport_right) / 2;
    world_pan_center_y = (double) (geometry->viewport_top + geometry->viewport_bottom) / 2;
  }

#if DEBUG
  printf("relative zoomfactor: %E\n", relativ_zoom_factor);
  printf("new center: x: %E, y: %E \n",
         world_pan_center_x, world_pan_center_y);
#endif


  /* calculate new window and draw it */
  gschem_page_view_pan_general (page_view,
                                world_pan_center_x,
                                world_pan_center_y,
                                relativ_zoom_factor);

  /* Before warping the cursor, filter out any consecutive scroll events
   * from the event queue.  If the program receives more than one scroll
   * event before it can process the first one, then the globals mouse_x
   * and mouse_y won't contain the proper mouse position,
   * because the handler for the mouse moved event needs to
   * run first to set these values.
   */
  GdkEvent *topEvent = gdk_event_get();
  while( topEvent != NULL ) {
    if( topEvent->type != GDK_SCROLL ) {
      gdk_event_put( topEvent );
      gdk_event_free( topEvent );
      break;
    }
    gdk_event_free( topEvent );
    topEvent = gdk_event_get();
  }

  /* warp the cursor to the right position */
  if (w_current->warp_cursor) {
     gschem_page_view_WORLDtoSCREEN (page_view,
                                     world_pan_center_x, world_pan_center_y,
                                     &start_x, &start_y);
     x_basic_warp_cursor (GTK_WIDGET (page_view), start_x, start_y);
  }
}