[gnome-shell/wip/fmuellner/color-picker: 3/5] screenshot: Add pick_color() method
- From: Florian Müllner <fmuellner src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-shell/wip/fmuellner/color-picker: 3/5] screenshot: Add pick_color() method
- Date: Mon, 30 Jul 2018 16:59:02 +0000 (UTC)
commit be84a00022cd75528a842fcc8730c1bca66d7eb4
Author: Florian Müllner <fmuellner gnome org>
Date: Thu Jul 19 14:50:49 2018 +0200
screenshot: Add pick_color() method
Graphical applications like GIMP or GIMP allow picking colors from
any location on-screen. In order to keep supporting this feature
on wayland and in sandboxed apps, we will expose an appropriate
method in the Screenshot interface, so first add a corresponding
method to ShellScreenshot.
https://gitlab.gnome.org/GNOME/gnome-shell/issues/286
src/shell-screenshot.c | 122 +++++++++++++++++++++++++++++++++++++++++++++++++
src/shell-screenshot.h | 10 ++++
2 files changed, 132 insertions(+)
---
diff --git a/src/shell-screenshot.c b/src/shell-screenshot.c
index f26ff64b5..4a119a153 100644
--- a/src/shell-screenshot.c
+++ b/src/shell-screenshot.c
@@ -456,6 +456,27 @@ grab_window_screenshot (ClutterActor *stage,
g_object_unref (task);
}
+static void
+grab_pixel (ClutterActor *stage,
+ GTask *result)
+{
+ ShellScreenshot *screenshot = g_task_get_source_object (result);
+ ShellScreenshotPrivate *priv = screenshot->priv;
+
+ do_grab_screenshot (screenshot,
+ CLUTTER_STAGE (stage),
+ priv->screenshot_area.x,
+ priv->screenshot_area.y,
+ 1,
+ 1);
+
+ meta_enable_unredirect_for_display (shell_global_get_display (priv->global));
+
+ g_signal_handlers_disconnect_by_func (stage, grab_pixel, result);
+ g_task_return_boolean (result, TRUE);
+ g_object_unref (result);
+}
+
static gboolean
finish_screenshot (ShellScreenshot *screenshot,
GAsyncResult *result,
@@ -731,6 +752,107 @@ shell_screenshot_screenshot_window_finish (ShellScreenshot *screenshot,
return finish_screenshot (screenshot, result, area, filename_used, error);
}
+/**
+ * shell_screenshot_pick_color:
+ * @screenshot: the #ShellScreenshot
+ * @x: The X coordinate to pick
+ * @y: The Y coordinate to pick
+ * @callback: (scope async): function to call returning success or failure
+ * of the async grabbing
+ *
+ * Picks the pixel at @x, @y and returns its color as #ClutterColor.
+ *
+ */
+void
+shell_screenshot_pick_color (ShellScreenshot *screenshot,
+ int x,
+ int y,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ ShellScreenshotPrivate *priv = screenshot->priv;
+ MetaDisplay *display = shell_global_get_display (priv->global);
+ ClutterActor *stage;
+ GTask *result;
+
+ result = g_task_new (screenshot, NULL, callback, user_data);
+ g_task_set_source_tag (result, shell_screenshot_pick_color);
+
+ priv->screenshot_area.x = x;
+ priv->screenshot_area.y = y;
+ priv->screenshot_area.width = 1;
+ priv->screenshot_area.height = 1;
+
+ stage = CLUTTER_ACTOR (shell_global_get_stage (priv->global));
+
+ meta_disable_unredirect_for_display (display);
+
+ g_signal_connect_after (stage, "paint", G_CALLBACK (grab_pixel), result);
+
+ clutter_actor_queue_redraw (stage);
+}
+
+#if G_BYTE_ORDER == G_LITTLE_ENDIAN
+#define INDEX_A 3
+#define INDEX_R 2
+#define INDEX_G 1
+#define INDEX_B 0
+#else
+#define INDEX_A 0
+#define INDEX_R 1
+#define INDEX_G 2
+#define INDEX_B 3
+#endif
+
+/**
+ * shell_screenshot_pick_color_finish:
+ * @screenshot: the #ShellScreenshot
+ * @result: the #GAsyncResult that was provided to the callback
+ * @color: (out caller-allocates): the picked color
+ * @error: #GError for error reporting
+ *
+ * Finish the asynchronous operation started by shell_screenshot_pick_color()
+ * and obtain its result.
+ *
+ * Returns: whether the operation was successful
+ *
+ */
+gboolean
+shell_screenshot_pick_color_finish (ShellScreenshot *screenshot,
+ GAsyncResult *result,
+ ClutterColor *color,
+ GError **error)
+{
+ ShellScreenshotPrivate *priv = screenshot->priv;
+
+ g_return_val_if_fail (g_async_result_is_tagged (result,
+ shell_screenshot_pick_color),
+ FALSE);
+
+ if (!g_task_propagate_boolean (G_TASK (result), error))
+ return FALSE;
+
+ /* protect against mutter changing the format used for stage captures */
+ g_assert (cairo_image_surface_get_format (priv->image) == CAIRO_FORMAT_ARGB32);
+
+ if (color)
+ {
+ uint8_t *data = cairo_image_surface_get_data (priv->image);
+
+ color->alpha = data[INDEX_A];
+ color->red = data[INDEX_R];
+ color->green = data[INDEX_G];
+ color->blue = data[INDEX_B];
+ }
+
+ return TRUE;
+}
+
+#undef INDEX_A
+#undef INDEX_R
+#undef INDEX_G
+#undef INDEX_B
+
ShellScreenshot *
shell_screenshot_new (void)
{
diff --git a/src/shell-screenshot.h b/src/shell-screenshot.h
index 61178e2ec..2367d518e 100644
--- a/src/shell-screenshot.h
+++ b/src/shell-screenshot.h
@@ -53,4 +53,14 @@ gboolean shell_screenshot_screenshot_finish (ShellScreenshot *screensho
const char **filename_used,
GError **error);
+void shell_screenshot_pick_color (ShellScreenshot *screenshot,
+ int x,
+ int y,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+gboolean shell_screenshot_pick_color_finish (ShellScreenshot *screenshot,
+ GAsyncResult *result,
+ ClutterColor *color,
+ GError **error);
+
#endif /* ___SHELL_SCREENSHOT_H__ */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]