static gboolean gimp_pick_button_mouse_release (GtkWidget *invisible, GdkEventButton *event, GimpPickButton *button) { gint x_root; gint y_root; if (event->button != 1) return FALSE; gdk_window_get_origin (event->window, &x_root, &y_root); x_root += event->x; y_root += event->y; gimp_pick_button_pick (gdk_event_get_screen ((GdkEvent *) event), x_root, y_root, button); gimp_pick_button_shutdown (button); g_signal_handlers_disconnect_by_func (invisible, gimp_pick_button_mouse_motion, button); g_signal_handlers_disconnect_by_func (invisible, gimp_pick_button_mouse_release, button); return TRUE; }
static gboolean gstyle_eyedropper_pointer_released_cb (GstyleEyedropper *self, GdkEventButton *event, GtkWindow *window) { GdkRGBA rgba; g_assert (GSTYLE_IS_EYEDROPPER (self)); g_assert (event != NULL); g_assert (GTK_IS_WINDOW (window)); g_assert (self->screen == gdk_event_get_screen ((GdkEvent *) event)); get_rgba_at_cursor (self, self->screen, gdk_event_get_device ((GdkEvent *) event), event->x_root, event->y_root, &rgba); gstyle_color_set_rgba (self->color, &rgba); g_signal_emit (self, signals [COLOR_PICKED], 0, &rgba); release_grab (self); self->button_pressed = FALSE; return GDK_EVENT_STOP; }
static gboolean gstyle_eyedropper_pointer_wheel_cb (GstyleEyedropper *self, GdkEventScroll *event, GtkWindow *window) { g_assert (GSTYLE_IS_EYEDROPPER (self)); g_assert (event != NULL); g_assert (GTK_IS_WINDOW (window)); g_assert (self->screen == gdk_event_get_screen ((GdkEvent *) event)); if (event->type == GDK_SCROLL) { if (event->direction == GDK_SCROLL_UP) increase_zoom_factor (self); else if (event->direction == GDK_SCROLL_DOWN) decrease_zoom_factor (self); else return GDK_EVENT_PROPAGATE; } else return GDK_EVENT_PROPAGATE; gstyle_eyedropper_draw_zoom_area (self, event->x_root, event->y_root); return GDK_EVENT_STOP; }
static void gstyle_eyedropper_pointer_motion_notify_cb (GstyleEyedropper *self, GdkEventMotion *event, GtkWindow *window) { GdkRGBA rgba; gint x_root, y_root; gint x, y; g_assert (GSTYLE_IS_EYEDROPPER (self)); g_assert (GTK_IS_WINDOW (window)); g_assert (event != NULL); g_assert (self->screen == gdk_event_get_screen ((GdkEvent *) event)); gstyle_eyedropper_event_get_root_coords (self, (GdkEvent *)event, &x_root, &y_root); gstyle_eyedropper_calculate_window_position (self, GTK_WINDOW (self->window), event->x_root, event->y_root, &x, &y); gtk_window_move (GTK_WINDOW (self->window), x, y); gstyle_eyedropper_draw_zoom_area (self, event->x_root, event->y_root); get_rgba_at_cursor (self, self->screen, gdk_event_get_device ((GdkEvent *) event), event->x_root, event->y_root, &rgba); gstyle_color_set_rgba (self->color, &rgba); if (self->button_pressed) g_signal_emit (self, signals [COLOR_PICKED], 0, &rgba); }
static GdkFilterReturn panel_action_protocol_filter (GdkXEvent *gdk_xevent, GdkEvent *event, gpointer data) { GdkWindow *window; GdkScreen *screen; #if GTK_CHECK_VERSION (3, 0, 0) GdkDisplay *display; #endif XEvent *xevent = (XEvent *) gdk_xevent; if (xevent->type != ClientMessage) return GDK_FILTER_CONTINUE; if ((xevent->xclient.message_type != atom_mate_panel_action) && (xevent->xclient.message_type != atom_gnome_panel_action)) return GDK_FILTER_CONTINUE; #if GTK_CHECK_VERSION (3, 0, 0) screen = gdk_event_get_screen (event); display = gdk_screen_get_display (screen); window = gdk_x11_window_lookup_for_display (display, xevent->xclient.window); #else window = gdk_window_lookup (xevent->xclient.window); screen = gdk_drawable_get_screen (window); #endif if (!window) return GDK_FILTER_CONTINUE; #if GTK_CHECK_VERSION (3, 0, 0) if (window != gdk_screen_get_root_window (screen)) return GDK_FILTER_CONTINUE; #endif if (xevent->xclient.data.l [0] == atom_mate_panel_action_main_menu) panel_action_protocol_main_menu (screen, xevent->xclient.data.l [1]); else if (xevent->xclient.data.l [0] == atom_mate_panel_action_run_dialog) panel_action_protocol_run_dialog (screen, xevent->xclient.data.l [1]); else if (xevent->xclient.data.l [0] == atom_gnome_panel_action_main_menu) panel_action_protocol_main_menu (screen, xevent->xclient.data.l [1]); else if (xevent->xclient.data.l [0] == atom_gnome_panel_action_run_dialog) panel_action_protocol_run_dialog (screen, xevent->xclient.data.l [1]); else if (xevent->xclient.data.l [0] == atom_mate_panel_action_kill_dialog) panel_action_protocol_kill_dialog (screen, xevent->xclient.data.l [1]); else return GDK_FILTER_CONTINUE; return GDK_FILTER_REMOVE; }
static gboolean gimp_pick_button_mouse_motion (GtkWidget *invisible, GdkEventMotion *event, GimpPickButton *button) { gint x_root; gint y_root; gdk_window_get_origin (event->window, &x_root, &y_root); x_root += event->x; y_root += event->y; gimp_pick_button_pick (gdk_event_get_screen ((GdkEvent *) event), x_root, y_root, button); return TRUE; }
static GdkFilterReturn panel_action_protocol_filter (GdkXEvent *gdk_xevent, GdkEvent *event, gpointer data) { GdkWindow *window; GdkScreen *screen; GdkDisplay *display; XEvent *xevent = (XEvent *) gdk_xevent; Atom atom; if (xevent->type != ClientMessage) return GDK_FILTER_CONTINUE; if (xevent->xclient.message_type != atom_gnome_panel_action) return GDK_FILTER_CONTINUE; screen = gdk_event_get_screen (event); display = gdk_screen_get_display (screen); window = gdk_x11_window_lookup_for_display (display, xevent->xclient.window); if (!window) return GDK_FILTER_CONTINUE; if (window != gdk_screen_get_root_window (screen)) return GDK_FILTER_CONTINUE; atom = xevent->xclient.data.l[0]; if (atom == atom_gnome_panel_action_main_menu) panel_action_protocol_main_menu (screen, xevent->xclient.data.l [1]); else if (atom == atom_gnome_panel_action_run_dialog) panel_action_protocol_run_dialog (screen, xevent->xclient.data.l [1]); else if (atom == atom_gnome_panel_action_kill_dialog) panel_action_protocol_kill_dialog (screen, xevent->xclient.data.l [1]); else return GDK_FILTER_CONTINUE; return GDK_FILTER_REMOVE; }
static VALUE gdkevent_screen(VALUE self) { return GOBJ2RVAL(gdk_event_get_screen(RVAL2GDKEVENT(self))); }
void gstyle_eyedropper_set_source_event (GstyleEyedropper *self, GdkEvent *event) { GtkWidget *source; GtkStyleContext *context; GtkWidget *box; GtkWidget *swatch; GdkGrabStatus status; gint x_root, y_root; gint x, y; g_return_if_fail (GSTYLE_IS_EYEDROPPER (self)); g_return_if_fail (event != NULL); self->seat = g_object_ref (gdk_event_get_seat (event)); source = gtk_get_event_widget (event); self->screen = gdk_event_get_screen (event); g_signal_connect_swapped (self->screen, "size-changed", G_CALLBACK (gstyle_eyedropper_screen_size_changed_cb), self); self->window = g_object_ref_sink (gtk_window_new (GTK_WINDOW_POPUP)); gtk_window_set_screen (GTK_WINDOW (self->window),self->screen); gtk_widget_set_name (self->window, "gstyleeyedropper"); context = gtk_widget_get_style_context (self->window); self->default_provider = gstyle_css_provider_init_default (gtk_style_context_get_screen (context)); box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6); gtk_container_add (GTK_CONTAINER (self->window), box); self->zoom_area = gtk_drawing_area_new (); gtk_widget_set_size_request (self->zoom_area, ZOOM_AREA_WIDTH, ZOOM_AREA_HEIGHT); gtk_container_add (GTK_CONTAINER (box), self->zoom_area); swatch = g_object_new (GSTYLE_TYPE_COLOR_WIDGET, "fallback-name-kind", GSTYLE_COLOR_KIND_RGB_HEX6, "fallback-name-visible", TRUE, "color", self->color, NULL); gtk_container_add (GTK_CONTAINER (box), swatch); g_signal_connect_object (self->zoom_area, "draw", G_CALLBACK (gstyle_eyedropper_zoom_area_draw_cb), self, G_CONNECT_SWAPPED); self->screen_width = gdk_screen_get_width (self->screen); self->screen_height = gdk_screen_get_height (self->screen); gstyle_eyedropper_event_get_root_coords (self, event, &x_root, &y_root); gstyle_eyedropper_calculate_window_position (self, GTK_WINDOW (self->window), x_root, y_root, &x, &y); gtk_window_move (GTK_WINDOW (self->window), x, y); gtk_widget_show_all (self->window); gtk_widget_add_events (self->window, GDK_BUTTON_RELEASE_MASK | GDK_BUTTON_PRESS_MASK | GDK_POINTER_MOTION_MASK); self->cursor = gdk_cursor_new_from_name (gdk_screen_get_display (self->screen), "cell"); gtk_grab_add (self->window); status = gdk_seat_grab (self->seat, gtk_widget_get_window (source), GDK_SEAT_CAPABILITY_ALL, FALSE, self->cursor, event, NULL, NULL); if (status != GDK_GRAB_SUCCESS) { g_warning ("grab failed status:%i\n", status); return; } self->motion_notify_handler_id = g_signal_connect_swapped (self->window, "motion-notify-event", G_CALLBACK (gstyle_eyedropper_pointer_motion_notify_cb), self); self->pointer_pressed_handler_id = g_signal_connect_swapped (self->window, "button-press-event", G_CALLBACK (gstyle_eyedropper_pointer_pressed_cb), self); self->pointer_wheel_handler_id = g_signal_connect_swapped (self->window, "scroll-event", G_CALLBACK (gstyle_eyedropper_pointer_wheel_cb), self); self->key_handler_id = g_signal_connect_swapped (self->window, "key-press-event", G_CALLBACK (gstyle_eyedropper_key_pressed_cb), self); self->grab_broken_handler_id = g_signal_connect_swapped (self->window, "grab-broken-event", G_CALLBACK (gstyle_eyedropper_grab_broken_cb), self); }
static VALUE gdkevent_screen(VALUE self) { return GOBJ2RVAL(gdk_event_get_screen(get_gdkevent(self))); }
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); }