Beispiel #1
0
/* FIXME remove when gtknotebook's func for this becomes public, bug #.... */
static NautilusNotebook *
find_notebook_at_pointer (gint abs_x, gint abs_y)
{
	GdkDeviceManager *manager;
	GdkDevice *pointer;
	GdkWindow *win_at_pointer, *toplevel_win;
	gpointer toplevel = NULL;
	gint x, y;

	/* FIXME multi-head */
	manager = gdk_display_get_device_manager (gdk_display_get_default ());
	pointer = gdk_device_manager_get_client_pointer (manager);
	win_at_pointer = gdk_device_get_window_at_position (pointer, &x, &y);

	if (win_at_pointer == NULL)
	{
		/* We are outside all windows containing a notebook */
		return NULL;
	}

	toplevel_win = gdk_window_get_toplevel (win_at_pointer);

	/* get the GtkWidget which owns the toplevel GdkWindow */
	gdk_window_get_user_data (toplevel_win, &toplevel);

	/* toplevel should be an NautilusWindow */
	if (toplevel != NULL && NAUTILUS_IS_WINDOW (toplevel))
	{
		return NAUTILUS_NOTEBOOK (NAUTILUS_WINDOW (toplevel)->details->notebook);
	}

	return NULL;
}
GdkWindow *
do_find_current_window (void)
{
  GdkWindow *current_window;
  GdkDeviceManager *manager;
  GdkDevice *device;

  current_window = screenshot_find_active_window ();
  manager = gdk_display_get_device_manager (gdk_display_get_default ());
  device = gdk_device_manager_get_client_pointer (manager);
  
  /* If there's no active window, we fall back to returning the
   * window that the cursor is in.
   */
  if (!current_window)
    current_window = gdk_device_get_window_at_position (device, NULL, NULL);

  if (current_window)
    {
      if (screenshot_window_is_desktop (current_window))
	/* if the current window is the desktop (e.g. nautilus), we
	 * return NULL, as getting the whole screen makes more sense.
         */
        return NULL;

      /* Once we have a window, we take the toplevel ancestor. */
      current_window = gdk_window_get_toplevel (current_window);
    }

  return current_window;
}
Beispiel #3
0
static void tooltip_trigger(void)
{
	GdkDisplay *display = gdk_display_get_default();
#if GTK_CHECK_VERSION(3, 0, 0)
	GdkDeviceManager *manager = gdk_display_get_device_manager(display);
	GdkDevice *device = gdk_device_manager_get_client_pointer(manager);
	GdkWindow *window = gdk_device_get_window_at_position(device, NULL, NULL);
#else
	GdkWindow *window = gdk_display_get_window_at_pointer(display, NULL, NULL);
#endif
	GeanyDocument *doc = document_get_current();

	if (doc && window)
	{
		GtkWidget *event_widget;

		gdk_window_get_user_data(window, (void **) &event_widget);
		/* if you know a better working way, do not hesistate to tell me */
		if (event_widget &&
			gtk_widget_is_ancestor(event_widget, GTK_WIDGET(doc->editor->sci)))
		{
			gtk_tooltip_trigger_tooltip_query(display);
		}
	}
}
Beispiel #4
0
/**
 * gtk_tooltip_trigger_tooltip_query:
 * @display: a #GdkDisplay
 *
 * Triggers a new tooltip query on @display, in order to update the current
 * visible tooltip, or to show/hide the current tooltip.  This function is
 * useful to call when, for example, the state of the widget changed by a
 * key press.
 *
 * Since: 2.12
 */
void
gtk_tooltip_trigger_tooltip_query (GdkDisplay *display)
{
  gint x, y;
  GdkWindow *window;
  GdkEvent event;
  GdkDevice *device;

  /* Trigger logic as if the mouse moved */
  device = gdk_device_manager_get_client_pointer (gdk_display_get_device_manager (display));
  window = gdk_device_get_window_at_position (device, &x, &y);
  if (!window)
    return;

  event.type = GDK_MOTION_NOTIFY;
  event.motion.window = window;
  event.motion.x = x;
  event.motion.y = y;
  event.motion.is_hint = FALSE;

  gdk_window_get_root_coords (window, x, y, &x, &y);
  event.motion.x_root = x;
  event.motion.y_root = y;

  _gtk_tooltip_handle_event (&event);
}
Beispiel #5
0
void DragAndDropHandler::finishDrag(GdkDragContext* context)
{
#if GTK_CHECK_VERSION(3, 16, 0)
    // This can happen when attempting to call finish drag from webkitWebViewBaseDragEnd()
    // for a obsolete DnD operation that got previously cancelled in startDrag().
    if (m_dragContext.get() != context)
        return;

    if (!m_draggingSelectionData)
        return;

    m_dragContext = nullptr;
    m_draggingSelectionData = nullptr;
#else
    if (!m_draggingSelectionDataMap.remove(context))
        return;
#endif

    GdkDevice* device = gdk_drag_context_get_device(context);
    int x = 0, y = 0;
    gdk_device_get_window_at_position(device, &x, &y);
    int xRoot = 0, yRoot = 0;
    gdk_device_get_position(device, nullptr, &xRoot, &yRoot);
    m_page.dragEnded(IntPoint(x, y), IntPoint(xRoot, yRoot), gdkDragActionToDragOperation(gdk_drag_context_get_selected_action(context)));
}
Beispiel #6
0
void DragAndDropHandler::finishDrag(GdkDragContext* context)
{
    if (!m_draggingDataObjects.remove(context))
        return;

    GdkDevice* device = gdk_drag_context_get_device(context);
    int x = 0, y = 0;
    gdk_device_get_window_at_position(device, &x, &y);
    int xRoot = 0, yRoot = 0;
    gdk_device_get_position(device, nullptr, &xRoot, &yRoot);
    m_page.dragEnded(IntPoint(x, y), IntPoint(xRoot, yRoot), gdkDragActionToDragOperation(gdk_drag_context_get_selected_action(context)));
}
Beispiel #7
0
/**
 * Hides the volume popup_window, connected via the signals
 * button-press-event, key-press-event and grab-broken-event.
 *
 * @param widget the object which received the signal
 * @param event the GdkEventButton which triggered the signal
 * @param user_data user data set when the signal handler was connected
 * @return TRUE to stop other handlers from being invoked for the evend,
 * FALSE to propagate the event further
 */
gboolean
hide_me(G_GNUC_UNUSED GtkWidget *widget,
		GdkEvent *event, G_GNUC_UNUSED gpointer user_data)
{
#ifdef WITH_GTK3
	GdkDevice *device = gtk_get_current_event_device();
#endif
	gint x, y;

	switch (event->type) {
	/* If a click happens outside of the popup, hide it */
	case GDK_BUTTON_PRESS:
		if (
#ifdef WITH_GTK3
			!gdk_device_get_window_at_position(device, &x, &y)
#else
			!gdk_window_at_pointer(&x, &y)
#endif
		)
			gtk_widget_hide(popup_window);
		break;

	/* If 'Esc' is pressed, hide popup */
	case GDK_KEY_PRESS:
		if (event->key.keyval == GDK_KEY_Escape) {
			gtk_widget_hide(popup_window);
		}
		break;

	/* Broken grab, hide popup */
	case GDK_GRAB_BROKEN:
		gtk_widget_hide(popup_window);
		break;

	/* Unhandle event, do nothing */
	default:
		break;
	}

	return FALSE;
}
Beispiel #8
0
/* Finds the toplevel window under the mouse pointer, if any.
 */
static GtkWidget *
find_toplevel_at_pointer (GdkDisplay *display)
{
  GdkWindow *pointer_window;
  GtkWidget *widget = NULL;

  pointer_window = gdk_device_get_window_at_position (gtk_get_current_event_device (),
                                                      NULL, NULL);

  /* The user data field of a GdkWindow is used to store a pointer
   * to the widget that created it.
   */
  if (pointer_window)
    {
      gpointer widget_ptr;
      gdk_window_get_user_data (pointer_window, &widget_ptr);
      widget = widget_ptr;
    }

  return widget ? gtk_widget_get_toplevel (widget) : NULL;
}
static void
get_rgba_at_cursor (GstyleEyedropper *self,
                    GdkScreen        *screen,
                    GdkDevice        *device,
                    gint              x,
                    gint              y,
                    GdkRGBA          *rgba)
{
  GdkWindow *window;
  GdkPixbuf *pixbuf;
  guchar *pixels;

  g_assert (GSTYLE_IS_EYEDROPPER (self));
  g_assert (GDK_IS_SCREEN (screen));
  g_assert (GDK_IS_DEVICE (device));

  window = gdk_screen_get_root_window (screen);
  pixbuf = gdk_pixbuf_get_from_window (window, x, y, 1, 1);
  if (!pixbuf)
    {
      window = gdk_device_get_window_at_position (device, &x, &y);
      if (!window)
        return;

      pixbuf = gdk_pixbuf_get_from_window (window, x, y, 1, 1);
      if (!pixbuf)
        return;
    }

  g_assert (gdk_pixbuf_get_colorspace (pixbuf) == GDK_COLORSPACE_RGB);
  g_assert (gdk_pixbuf_get_bits_per_sample (pixbuf) == 8);

  pixels = gdk_pixbuf_get_pixels (pixbuf);
  rgba->red = pixels[0] / 255.0;
  rgba->green = pixels[1] / 255.0;
  rgba->blue = pixels[2] /255.0;
  rgba->alpha = 1.0;

  g_object_unref (pixbuf);
}
Beispiel #10
0
/* FIXME remove when gtknotebook's func for this becomes public, bug #.... */
static CajaNotebook *
find_notebook_at_pointer (gint abs_x, gint abs_y)
{
#if GTK_CHECK_VERSION(3, 0, 0)
    GdkDeviceManager *manager;
    GdkDevice *pointer;
#endif
    GdkWindow *win_at_pointer, *toplevel_win;
    gpointer toplevel = NULL;
    gint x, y;

    /* FIXME multi-head */
#if GTK_CHECK_VERSION(3, 0, 0)
    manager = gdk_display_get_device_manager (gdk_display_get_default ());
    pointer = gdk_device_manager_get_client_pointer (manager);
    win_at_pointer = gdk_device_get_window_at_position (pointer, &x, &y);
#else
    win_at_pointer = gdk_window_at_pointer (&x, &y);
#endif

    if (win_at_pointer == NULL)
    {
        /* We are outside all windows containing a notebook */
        return NULL;
    }

    toplevel_win = gdk_window_get_toplevel (win_at_pointer);

    /* get the GtkWidget which owns the toplevel GdkWindow */
    gdk_window_get_user_data (toplevel_win, &toplevel);

    /* toplevel should be an CajaWindow */
    if (toplevel != NULL && CAJA_IS_NAVIGATION_WINDOW (toplevel))
    {
        return CAJA_NOTEBOOK (CAJA_NAVIGATION_WINDOW_PANE (CAJA_WINDOW (toplevel)->details->active_pane)->notebook);
    }

    return NULL;
}
Beispiel #11
0
/**
 * Handles 'button-press-event', 'key-press-event' and 'grab-broken-event' signals,
 * on the GtkWindow. Used to hide the volume popup window.
 *
 * @param widget the object which received the signal.
 * @param event the GdkEvent which triggered this signal.
 * @param window user data set when the signal handler was connected.
 * @return TRUE to stop other handlers from being invoked for the event.
 * FALSE to propagate the event further.
 */
gboolean
on_popup_window_event(G_GNUC_UNUSED GtkWidget *widget, GdkEvent *event,
                      PopupWindow *window)
{
	switch (event->type) {

	/* If a click happens outside of the popup, hide it */
	case GDK_BUTTON_PRESS: {
		gint x, y;
#ifdef WITH_GTK3
		GdkDevice *device = gtk_get_current_event_device();

		if (!gdk_device_get_window_at_position(device, &x, &y))
#else
		if (!gdk_window_at_pointer(&x, &y))
#endif
			popup_window_hide(window);

		break;
	}

	/* If 'Esc' is pressed, hide popup */
	case GDK_KEY_PRESS:
		if (event->key.keyval == GDK_KEY_Escape)
			popup_window_hide(window);
		break;

	/* Broken grab, hide popup */
	case GDK_GRAB_BROKEN:
		popup_window_hide(window);
		break;

	/* Unhandle event, do nothing */
	default:
		break;
	}

	return FALSE;
}
Beispiel #12
0
static GtkWidget *
find_widget_at_pointer (GdkDevice *device)
{
  GtkWidget *widget = NULL;
  GdkWindow *pointer_window;
  gint x, y;
  FindWidgetData data;

  pointer_window = gdk_device_get_window_at_position (device, NULL, NULL);

  if (pointer_window)
    {
      gpointer widget_ptr;

      gdk_window_get_user_data (pointer_window, &widget_ptr);
      widget = widget_ptr;
    }

  if (widget)
    {
      gdk_window_get_device_position (gtk_widget_get_window (widget),
                                      device, &x, &y, NULL);

      data.x = x;
      data.y = y;
      data.found = FALSE;
      data.first = TRUE;

      find_widget (widget, &data);
      if (data.found)
        return data.res_widget;

      return widget;
    }

  return NULL;
}
Beispiel #13
0
gboolean
gdk_input_other_event (GdkDisplay *display,
                       GdkEvent   *event,
                       MSG        *msg,
                       GdkWindow  *window)
{
  GdkDeviceManagerWin32 *device_manager;
  GdkDeviceWintab *source_device = NULL;
  GdkDeviceGrabInfo *last_grab;
  GdkEventMask masktest;
  guint key_state;
  POINT pt;

  PACKET packet;
  gint root_x, root_y;
  gint num_axes;
  gint x, y;
  guint translated_buttons, button_diff, button_mask;
  /* Translation from tablet button state to GDK button state for
   * buttons 1-3 - swap button 2 and 3.
   */
  static guint button_map[8] = {0, 1, 4, 5, 2, 3, 6, 7};

  if (event->any.window != wintab_window)
    {
      g_warning ("gdk_input_other_event: not wintab_window?");
      return FALSE;
    }

G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
  device_manager = GDK_DEVICE_MANAGER_WIN32 (gdk_display_get_device_manager (display));
G_GNUC_END_IGNORE_DEPRECATIONS;
  window = gdk_device_get_window_at_position (device_manager->core_pointer, &x, &y);
  if (window == NULL)
    window = gdk_get_default_root_window ();

  g_object_ref (window);

  GDK_NOTE (EVENTS_OR_INPUT,
	    g_print ("gdk_input_other_event: window=%p %+d%+d\n",
               GDK_WINDOW_HWND (window), x, y));

  if (msg->message == WT_PACKET || msg->message == WT_CSRCHANGE)
    {
      if (!(*p_WTPacket) ((HCTX) msg->lParam, msg->wParam, &packet))
        return FALSE;
    }

  switch (msg->message)
    {
    case WT_PACKET:
      /* Don't produce any button or motion events while a window is being
       * moved or resized, see bug #151090.
       */
      if (_modal_operation_in_progress)
        {
          GDK_NOTE (EVENTS_OR_INPUT, g_print ("... ignored when moving/sizing\n"));
          return FALSE;
        }

      if ((source_device = gdk_device_manager_find_wintab_device (device_manager,
                                                                  (HCTX) msg->lParam,
                                                                  packet.pkCursor)) == NULL)
        return FALSE;

      if (gdk_device_get_mode (GDK_DEVICE (source_device)) == GDK_MODE_DISABLED)
        return FALSE;

      last_grab = _gdk_display_get_last_device_grab (display, GDK_DEVICE (source_device));

      if (last_grab && last_grab->window)
        {
          g_object_unref (window);

          window = g_object_ref (last_grab->window);
        }

      if (window == gdk_get_default_root_window ())
        {
          GDK_NOTE (EVENTS_OR_INPUT, g_print ("... is root\n"));
          return FALSE;
        }

      num_axes = 0;
      if (source_device->pktdata & PK_X)
        source_device->last_axis_data[num_axes++] = packet.pkX;
      if (source_device->pktdata & PK_Y)
        source_device->last_axis_data[num_axes++] = packet.pkY;
      if (source_device->pktdata & PK_NORMAL_PRESSURE)
        source_device->last_axis_data[num_axes++] = packet.pkNormalPressure;
      if (source_device->pktdata & PK_ORIENTATION)
        {
          decode_tilt (source_device->last_axis_data + num_axes,
                       source_device->orientation_axes, &packet);
          num_axes += 2;
        }

      translated_buttons = button_map[packet.pkButtons & 0x07] | (packet.pkButtons & ~0x07);

      if (translated_buttons != source_device->button_state)
        {
          /* At least one button has changed state so produce a button event
           * If more than one button has changed state (unlikely),
           * just care about the first and act on the next the next time
           * we get a packet
           */
          button_diff = translated_buttons ^ source_device->button_state;

          /* Gdk buttons are numbered 1.. */
          event->button.button = 1;

          for (button_mask = 1; button_mask != 0x80000000;
               button_mask <<= 1, event->button.button++)
            {
              if (button_diff & button_mask)
                {
                  /* Found a button that has changed state */
                  break;
                }
            }

          if (!(translated_buttons & button_mask))
            {
              event->any.type = GDK_BUTTON_RELEASE;
              masktest = GDK_BUTTON_RELEASE_MASK;
            }
          else
            {
              event->any.type = GDK_BUTTON_PRESS;
              masktest = GDK_BUTTON_PRESS_MASK;
            }
          source_device->button_state ^= button_mask;
        }
      else
        {
          event->any.type = GDK_MOTION_NOTIFY;
          masktest = GDK_POINTER_MOTION_MASK;
          if (source_device->button_state & (1 << 0))
            masktest |= GDK_BUTTON_MOTION_MASK | GDK_BUTTON1_MOTION_MASK;
          if (source_device->button_state & (1 << 1))
            masktest |= GDK_BUTTON_MOTION_MASK | GDK_BUTTON2_MOTION_MASK;
          if (source_device->button_state & (1 << 2))
            masktest |= GDK_BUTTON_MOTION_MASK | GDK_BUTTON3_MOTION_MASK;
        }

      /* Now we can check if the window wants the event, and
       * propagate if necessary.
       */
      while ((gdk_window_get_device_events (window, GDK_DEVICE (source_device)) & masktest) == 0 &&
	     (gdk_device_get_device_type (GDK_DEVICE (source_device)) == GDK_DEVICE_TYPE_SLAVE &&
	      (gdk_window_get_events (window) & masktest) == 0))
        {
          GDK_NOTE (EVENTS_OR_INPUT, g_print ("... not selected\n"));

          if (window->parent == gdk_get_default_root_window () || window->parent == NULL)
            return FALSE;

          pt.x = x;
          pt.y = y;
          ClientToScreen (GDK_WINDOW_HWND (window), &pt);
          g_object_unref (window);
          window = window->parent;
          g_object_ref (window);
          ScreenToClient (GDK_WINDOW_HWND (window), &pt);
          x = pt.x;
          y = pt.y;
          GDK_NOTE (EVENTS_OR_INPUT, g_print ("... propagating to %p %+d%+d\n",
                                              GDK_WINDOW_HWND (window), x, y));
        }

      event->any.window = window;
      key_state = get_modifier_key_state ();
      if (event->any.type == GDK_BUTTON_PRESS ||
          event->any.type == GDK_BUTTON_RELEASE)
        {
          event->button.time = _gdk_win32_get_next_tick (msg->time);
	  if (source_device->sends_core)
	    gdk_event_set_device (event, device_manager->core_pointer);
          gdk_event_set_source_device (event, GDK_DEVICE (source_device));
          gdk_event_set_seat (event, gdk_device_get_seat (device_manager->core_pointer));

          event->button.axes = g_new (gdouble, num_axes);
	  gdk_window_get_origin (window, &root_x, &root_y);

          _gdk_device_wintab_translate_axes (source_device,
                                             window,
                                             event->button.axes,
                                             &event->button.x,
                                             &event->button.y);

          event->button.x_root = event->button.x + root_x;
          event->button.y_root = event->button.y + root_y;

          event->button.state =
            key_state | ((source_device->button_state << 8)
                         & (GDK_BUTTON1_MASK | GDK_BUTTON2_MASK
                            | GDK_BUTTON3_MASK | GDK_BUTTON4_MASK
                            | GDK_BUTTON5_MASK));

          GDK_NOTE (EVENTS_OR_INPUT,
                    g_print ("WINTAB button %s:%d %g,%g\n",
                             (event->button.type == GDK_BUTTON_PRESS ?
                              "press" : "release"),
                             event->button.button,
                             event->button.x, event->button.y));
        }
      else
        {
          event->motion.time = _gdk_win32_get_next_tick (msg->time);
          event->motion.is_hint = FALSE;
          gdk_event_set_device (event, device_manager->core_pointer);
          gdk_event_set_source_device (event, GDK_DEVICE (source_device));
          gdk_event_set_seat (event, gdk_device_get_seat (device_manager->core_pointer));

          event->motion.axes = g_new (gdouble, num_axes);
	  gdk_window_get_origin (window, &root_x, &root_y);

          _gdk_device_wintab_translate_axes (source_device,
                                             window,
                                             event->motion.axes,
                                             &event->motion.x,
                                             &event->motion.y);

          event->motion.x_root = event->motion.x + root_x;
          event->motion.y_root = event->motion.y + root_y;

          event->motion.state =
            key_state | ((source_device->button_state << 8)
                         & (GDK_BUTTON1_MASK | GDK_BUTTON2_MASK
                            | GDK_BUTTON3_MASK | GDK_BUTTON4_MASK
                            | GDK_BUTTON5_MASK));

          GDK_NOTE (EVENTS_OR_INPUT,
                    g_print ("WINTAB motion: %g,%g\n",
                             event->motion.x, event->motion.y));
        }
      return TRUE;

    case WT_CSRCHANGE:
      if ((source_device = gdk_device_manager_find_wintab_device (device_manager,
                                                                  (HCTX) msg->lParam,
                                                                  packet.pkCursor)) == NULL)
        return FALSE;

      if (gdk_device_get_mode (GDK_DEVICE (source_device)) == GDK_MODE_DISABLED)
        return FALSE;

      if (source_device->sends_core)
	{
	  _gdk_device_virtual_set_active (device_manager->core_pointer, GDK_DEVICE (source_device));
	  _gdk_input_ignore_core = TRUE;
	}

      return FALSE;

    case WT_PROXIMITY:
      if (LOWORD (msg->lParam) == 0)
        {
	  _gdk_input_ignore_core = FALSE;
	  _gdk_device_virtual_set_active (device_manager->core_pointer,
					  device_manager->system_pointer);
        }

      return FALSE;
    }

  return FALSE;
}
Beispiel #14
0
static void
gimp_pick_button_pick (GimpPickButton *button,
                       GdkEvent       *event)
{
  GdkScreen        *screen = gdk_event_get_screen (event);
  GimpColorProfile *monitor_profile;
  GdkMonitor       *monitor;
  GimpRGB           rgb;
  gint              x_root;
  gint              y_root;
  gdouble           x_win;
  gdouble           y_win;

  gdk_window_get_origin (gdk_event_get_window (event), &x_root, &y_root);
  gdk_event_get_coords (event, &x_win, &y_win);
  x_root += x_win;
  y_root += y_win;

#ifdef G_OS_WIN32

  {
    HDC      hdc;
    RECT     rect;
    COLORREF win32_color;

    /* For MS Windows, use native GDI functions to get the pixel, as
     * cairo does not handle the case where you have multiple monitors
     * with a monitor on the left or above the primary monitor.  That
     * scenario create a cairo primary surface with negative extent,
     * which is not handled properly (bug 740634).
     */

    hdc = GetDC (HWND_DESKTOP);
    GetClipBox (hdc, &rect);
    win32_color = GetPixel (hdc, x_root + rect.left, y_root + rect.top);
    ReleaseDC (HWND_DESKTOP, hdc);

    gimp_rgba_set_uchar (&rgb,
                         GetRValue (win32_color),
                         GetGValue (win32_color),
                         GetBValue (win32_color),
                         255);
  }

#else

  {
    GdkWindow       *window;
    gint             x_window;
    gint             y_window;
    cairo_surface_t *image;
    cairo_t         *cr;
    guchar          *data;
    guchar           color[3];

    /* we try to pick from the local window under the cursor, and fall
     * back to picking from the root window if this fails (i.e., if
     * the cursor is not under a local window).  on wayland, picking
     * from the root window is not supported, so this at least allows
     * us to pick from local windows.  see bug #780375.
     */
    window = gdk_device_get_window_at_position (gdk_event_get_device (event),
                                                &x_window, &y_window);
    if (! window)
      {
        window   = gdk_screen_get_root_window (screen);
        x_window = x_root;
        y_window = y_root;
      }

    image = cairo_image_surface_create (CAIRO_FORMAT_RGB24, 1, 1);

    cr = cairo_create (image);

    gdk_cairo_set_source_window (cr, window, -x_window, -y_window);
    cairo_paint (cr);

    cairo_destroy (cr);

    data = cairo_image_surface_get_data (image);
    GIMP_CAIRO_RGB24_GET_PIXEL (data, color[0], color[1], color[2]);

    cairo_surface_destroy (image);

    gimp_rgba_set_uchar (&rgb, color[0], color[1], color[2], 255);
  }

#endif

  monitor = gdk_display_get_monitor_at_point (gdk_screen_get_display (screen),
                                              x_root, y_root);
  monitor_profile = gimp_monitor_get_color_profile (monitor);

  if (monitor_profile)
    {
      GimpColorProfile        *srgb_profile;
      GimpColorTransform      *transform;
      const Babl              *format;
      GimpColorTransformFlags  flags = 0;

      format = babl_format ("R'G'B'A double");

      flags |= GIMP_COLOR_TRANSFORM_FLAGS_NOOPTIMIZE;
      flags |= GIMP_COLOR_TRANSFORM_FLAGS_BLACK_POINT_COMPENSATION;

      srgb_profile = gimp_color_profile_new_rgb_srgb ();
      transform = gimp_color_transform_new (monitor_profile, format,
                                            srgb_profile,    format,
                                            GIMP_COLOR_RENDERING_INTENT_PERCEPTUAL,
                                            flags);
      g_object_unref (srgb_profile);

      if (transform)
        {
          gimp_color_transform_process_pixels (transform,
                                               format, &rgb,
                                               format, &rgb,
                                               1);
          gimp_rgb_clamp (&rgb);

          g_object_unref (transform);
        }
    }

  g_signal_emit_by_name (button, "color-picked", &rgb);
}