ShellScreenshot: replace XFixes usage with MetaCursorTracker
More X11 code going away from gnome-shell, and more wayland compatibility. https://bugzilla.gnome.org/show_bug.cgi?id=705911
This commit is contained in:
parent
d52c95a15f
commit
d272b0cbf3
@ -3,14 +3,13 @@
|
|||||||
#define COGL_ENABLE_EXPERIMENTAL_API
|
#define COGL_ENABLE_EXPERIMENTAL_API
|
||||||
#define CLUTTER_ENABLE_EXPERIMENTAL_API
|
#define CLUTTER_ENABLE_EXPERIMENTAL_API
|
||||||
|
|
||||||
#include <X11/extensions/Xfixes.h>
|
|
||||||
#include <clutter/x11/clutter-x11.h>
|
|
||||||
#include <clutter/clutter.h>
|
#include <clutter/clutter.h>
|
||||||
#include <cogl/cogl.h>
|
#include <cogl/cogl.h>
|
||||||
#include <meta/display.h>
|
#include <meta/display.h>
|
||||||
#include <meta/util.h>
|
#include <meta/util.h>
|
||||||
#include <meta/meta-plugin.h>
|
#include <meta/meta-plugin.h>
|
||||||
#include <meta/meta-shaped-texture.h>
|
#include <meta/meta-shaped-texture.h>
|
||||||
|
#include <meta/meta-cursor-tracker.h>
|
||||||
|
|
||||||
#include "shell-global.h"
|
#include "shell-global.h"
|
||||||
#include "shell-screenshot.h"
|
#include "shell-screenshot.h"
|
||||||
@ -246,58 +245,70 @@ do_grab_screenshot (_screenshot_data *screenshot_data,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_draw_cursor_image (cairo_surface_t *surface,
|
get_pointer_coords (int *x,
|
||||||
|
int *y)
|
||||||
|
{
|
||||||
|
ClutterDeviceManager *manager;
|
||||||
|
ClutterInputDevice *device;
|
||||||
|
ClutterPoint point;
|
||||||
|
|
||||||
|
manager = clutter_device_manager_get_default ();
|
||||||
|
device = clutter_device_manager_get_core_device (manager, CLUTTER_POINTER_DEVICE);
|
||||||
|
|
||||||
|
clutter_input_device_get_coords (device, NULL, &point);
|
||||||
|
*x = point.x;
|
||||||
|
*y = point.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_draw_cursor_image (MetaCursorTracker *tracker,
|
||||||
|
cairo_surface_t *surface,
|
||||||
cairo_rectangle_int_t area)
|
cairo_rectangle_int_t area)
|
||||||
{
|
{
|
||||||
XFixesCursorImage *cursor_image;
|
CoglTexture *texture;
|
||||||
|
int width, height;
|
||||||
|
int stride;
|
||||||
|
guint8 *data;
|
||||||
cairo_surface_t *cursor_surface;
|
cairo_surface_t *cursor_surface;
|
||||||
cairo_region_t *screenshot_region;
|
cairo_region_t *screenshot_region;
|
||||||
cairo_t *cr;
|
cairo_t *cr;
|
||||||
|
int x, y;
|
||||||
guchar *data;
|
int xhot, yhot;
|
||||||
int stride;
|
|
||||||
int i, j;
|
|
||||||
|
|
||||||
cursor_image = XFixesGetCursorImage (clutter_x11_get_default_display ());
|
|
||||||
|
|
||||||
if (!cursor_image)
|
|
||||||
return;
|
|
||||||
|
|
||||||
screenshot_region = cairo_region_create_rectangle (&area);
|
screenshot_region = cairo_region_create_rectangle (&area);
|
||||||
|
get_pointer_coords (&x, &y);
|
||||||
|
|
||||||
if (!cairo_region_contains_point (screenshot_region, cursor_image->x, cursor_image->y))
|
if (!cairo_region_contains_point (screenshot_region, x, y))
|
||||||
{
|
{
|
||||||
XFree (cursor_image);
|
|
||||||
cairo_region_destroy (screenshot_region);
|
cairo_region_destroy (screenshot_region);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
cursor_surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, cursor_image->width, cursor_image->height);
|
texture = meta_cursor_tracker_get_sprite (tracker);
|
||||||
|
meta_cursor_tracker_get_hot (tracker, &xhot, &yhot);
|
||||||
|
width = cogl_texture_get_width (texture);
|
||||||
|
height = cogl_texture_get_height (texture);
|
||||||
|
stride = 4 * width;
|
||||||
|
data = g_new (guint8, stride * height);
|
||||||
|
cogl_texture_get_data (texture, CLUTTER_CAIRO_FORMAT_ARGB32, stride, data);
|
||||||
|
|
||||||
/* The pixel data (in typical Xlib breakage) is longs even on
|
/* FIXME: cairo-gl? */
|
||||||
* 64-bit platforms, so we have to data-convert there. For simplicity,
|
cursor_surface = cairo_image_surface_create_for_data (data,
|
||||||
* just do it always
|
CAIRO_FORMAT_ARGB32,
|
||||||
*/
|
width, height,
|
||||||
data = cairo_image_surface_get_data (cursor_surface);
|
stride);
|
||||||
stride = cairo_image_surface_get_stride (cursor_surface);
|
|
||||||
for (i = 0; i < cursor_image->height; i++)
|
|
||||||
for (j = 0; j < cursor_image->width; j++)
|
|
||||||
*(guint32 *)(data + i * stride + 4 * j) = cursor_image->pixels[i * cursor_image->width + j];
|
|
||||||
|
|
||||||
cairo_surface_mark_dirty (cursor_surface);
|
|
||||||
|
|
||||||
cr = cairo_create (surface);
|
cr = cairo_create (surface);
|
||||||
cairo_set_source_surface (cr,
|
cairo_set_source_surface (cr,
|
||||||
cursor_surface,
|
cursor_surface,
|
||||||
cursor_image->x - cursor_image->xhot - area.x,
|
x - xhot - area.x,
|
||||||
cursor_image->y - cursor_image->yhot - area.y);
|
y - yhot - area.y);
|
||||||
cairo_paint (cr);
|
cairo_paint (cr);
|
||||||
|
|
||||||
cairo_destroy (cr);
|
cairo_destroy (cr);
|
||||||
cairo_surface_destroy (cursor_surface);
|
cairo_surface_destroy (cursor_surface);
|
||||||
cairo_region_destroy (screenshot_region);
|
cairo_region_destroy (screenshot_region);
|
||||||
XFree (cursor_image);
|
g_free (data);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -305,6 +316,7 @@ grab_screenshot (ClutterActor *stage,
|
|||||||
_screenshot_data *screenshot_data)
|
_screenshot_data *screenshot_data)
|
||||||
{
|
{
|
||||||
MetaScreen *screen = shell_global_get_screen (screenshot_data->screenshot->global);
|
MetaScreen *screen = shell_global_get_screen (screenshot_data->screenshot->global);
|
||||||
|
MetaCursorTracker *tracker;
|
||||||
int width, height;
|
int width, height;
|
||||||
GSimpleAsyncResult *result;
|
GSimpleAsyncResult *result;
|
||||||
GSettings *settings;
|
GSettings *settings;
|
||||||
@ -359,7 +371,10 @@ grab_screenshot (ClutterActor *stage,
|
|||||||
settings = g_settings_new (A11Y_APPS_SCHEMA);
|
settings = g_settings_new (A11Y_APPS_SCHEMA);
|
||||||
if (screenshot_data->include_cursor &&
|
if (screenshot_data->include_cursor &&
|
||||||
!g_settings_get_boolean (settings, MAGNIFIER_ACTIVE_KEY))
|
!g_settings_get_boolean (settings, MAGNIFIER_ACTIVE_KEY))
|
||||||
_draw_cursor_image (screenshot_data->image, screenshot_data->screenshot_area);
|
{
|
||||||
|
tracker = meta_cursor_tracker_get_for_screen (screen);
|
||||||
|
_draw_cursor_image (tracker, screenshot_data->image, screenshot_data->screenshot_area);
|
||||||
|
}
|
||||||
g_object_unref (settings);
|
g_object_unref (settings);
|
||||||
|
|
||||||
g_signal_handlers_disconnect_by_func (stage, (void *)grab_screenshot, (gpointer)screenshot_data);
|
g_signal_handlers_disconnect_by_func (stage, (void *)grab_screenshot, (gpointer)screenshot_data);
|
||||||
@ -488,6 +503,7 @@ shell_screenshot_screenshot_window (ShellScreenshot *screenshot,
|
|||||||
_screenshot_data *screenshot_data = g_new0 (_screenshot_data, 1);
|
_screenshot_data *screenshot_data = g_new0 (_screenshot_data, 1);
|
||||||
|
|
||||||
MetaScreen *screen = shell_global_get_screen (screenshot->global);
|
MetaScreen *screen = shell_global_get_screen (screenshot->global);
|
||||||
|
MetaCursorTracker *tracker;
|
||||||
MetaDisplay *display = meta_screen_get_display (screen);
|
MetaDisplay *display = meta_screen_get_display (screen);
|
||||||
MetaWindow *window = meta_display_get_focus_window (display);
|
MetaWindow *window = meta_display_get_focus_window (display);
|
||||||
ClutterActor *window_actor;
|
ClutterActor *window_actor;
|
||||||
@ -543,7 +559,10 @@ shell_screenshot_screenshot_window (ShellScreenshot *screenshot,
|
|||||||
|
|
||||||
settings = g_settings_new (A11Y_APPS_SCHEMA);
|
settings = g_settings_new (A11Y_APPS_SCHEMA);
|
||||||
if (include_cursor && !g_settings_get_boolean (settings, MAGNIFIER_ACTIVE_KEY))
|
if (include_cursor && !g_settings_get_boolean (settings, MAGNIFIER_ACTIVE_KEY))
|
||||||
_draw_cursor_image (screenshot_data->image, screenshot_data->screenshot_area);
|
{
|
||||||
|
tracker = meta_cursor_tracker_get_for_screen (screen);
|
||||||
|
_draw_cursor_image (tracker, screenshot_data->image, screenshot_data->screenshot_area);
|
||||||
|
}
|
||||||
g_object_unref (settings);
|
g_object_unref (settings);
|
||||||
|
|
||||||
result = g_simple_async_result_new (NULL, on_screenshot_written, (gpointer)screenshot_data, shell_screenshot_screenshot_window);
|
result = g_simple_async_result_new (NULL, on_screenshot_written, (gpointer)screenshot_data, shell_screenshot_screenshot_window);
|
||||||
|
Loading…
Reference in New Issue
Block a user