Commit 5b4ce13c authored by Andre Miranda's avatar Andre Miranda

Capture mouse cursor in rectangle selection (!5)

Fixes #30
parent 089e4e8c
......@@ -69,13 +69,20 @@ static GdkPixbuf *get_cursor_pixbuf (GdkDisplay *display
gint *cursory,
gint *xhot,
gint *yhot);
static void capture_cursor (GdkPixbuf *screenshot,
gint scale,
gint x,
gint y,
gint w,
gint h);
static GdkPixbuf *get_window_screenshot (GdkWindow *window,
gboolean show_mouse,
gboolean border);
static GdkFilterReturn region_filter_func (GdkXEvent *xevent,
GdkEvent *event,
RbData *rbdata);
static GdkPixbuf *get_rectangle_screenshot (gint delay);
static GdkPixbuf *get_rectangle_screenshot (gint delay,
gboolean show_mouse);
static gboolean cb_key_pressed (GtkWidget *widget,
GdkEventKey *event,
RubberBandData *rbdata);
......@@ -94,14 +101,14 @@ static gboolean cb_button_released (GtkWidget *wid
static gboolean cb_motion_notify (GtkWidget *widget,
GdkEventMotion *event,
RubberBandData *rbdata);
static GdkPixbuf *get_rectangle_screenshot_composited (gint delay);
static GdkPixbuf *get_rectangle_screenshot_composited (gint delay,
gboolean show_mouse);
/* Internals */
static Window
find_wm_window (Window xid)
{
......@@ -230,6 +237,66 @@ fallback:
}
static void capture_cursor (GdkPixbuf *screenshot,
gint scale,
gint x,
gint y,
gint w,
gint h)
{
gint cursorx, cursory, xhot, yhot;
GdkPixbuf *cursor_pixbuf;
GdkRectangle rectangle_window, rectangle_cursor;
cursor_pixbuf = get_cursor_pixbuf (gdk_display_get_default (),
gdk_get_default_root_window (),
&cursorx, &cursory, &xhot, &yhot);
if (G_UNLIKELY (cursor_pixbuf == NULL))
return;
/* rectangle_window stores the window coordinates */
rectangle_window.x = x * scale;
rectangle_window.y = y * scale;
rectangle_window.width = w * scale;
rectangle_window.height = h * scale;
/* rectangle_cursor stores the cursor coordinates */
rectangle_cursor.x = cursorx;
rectangle_cursor.y = cursory;
rectangle_cursor.width = gdk_pixbuf_get_width (cursor_pixbuf);
rectangle_cursor.height = gdk_pixbuf_get_height (cursor_pixbuf);
/* see if the pointer is inside the window */
if (gdk_rectangle_intersect (&rectangle_window,
&rectangle_cursor,
&rectangle_cursor))
{
int dest_x, dest_y;
TRACE ("Compose the two pixbufs");
dest_x = cursorx - rectangle_window.x - xhot;
dest_y = cursory - rectangle_window.y - yhot;
gdk_pixbuf_composite (cursor_pixbuf, screenshot,
CLAMP (dest_x, 0, dest_x),
CLAMP (dest_y, 0, dest_y),
rectangle_cursor.width,
rectangle_cursor.height,
dest_x,
dest_y,
1.0, 1.0,
GDK_INTERP_BILINEAR,
255);
}
g_object_unref (cursor_pixbuf);
}
static GdkPixbuf
*get_window_screenshot (GdkWindow *window,
gboolean show_mouse,
......@@ -399,59 +466,7 @@ static GdkPixbuf
}
if (show_mouse)
{
gint cursorx, cursory, xhot, yhot;
GdkPixbuf *cursor_pixbuf;
GdkDisplay *display = gdk_display_get_default ();
cursor_pixbuf = get_cursor_pixbuf (display, root, &cursorx, &cursory,
&xhot, &yhot);
if (G_LIKELY (cursor_pixbuf != NULL))
{
GdkRectangle rectangle_window, rectangle_cursor;
/* rectangle_window stores the window coordinates */
rectangle_window.x = x_orig * scale;
rectangle_window.y = y_orig * scale;
rectangle_window.width = width * scale;
rectangle_window.height = height * scale;
/* rectangle_cursor stores the cursor coordinates */
rectangle_cursor.x = cursorx;
rectangle_cursor.y = cursory;
rectangle_cursor.width =
gdk_pixbuf_get_width (cursor_pixbuf);
rectangle_cursor.height =
gdk_pixbuf_get_height (cursor_pixbuf);
/* see if the pointer is inside the window */
if (gdk_rectangle_intersect (&rectangle_window,
&rectangle_cursor,
&rectangle_cursor))
{
int dest_x, dest_y;
TRACE ("Compose the two pixbufs");
dest_x = cursorx - rectangle_window.x - xhot;
dest_y = cursory - rectangle_window.y - yhot;
gdk_pixbuf_composite (cursor_pixbuf, screenshot,
CLAMP (dest_x, 0, dest_x),
CLAMP (dest_y, 0, dest_y),
rectangle_cursor.width,
rectangle_cursor.height,
dest_x,
dest_y,
1.0, 1.0,
GDK_INTERP_BILINEAR,
255);
}
g_object_unref (cursor_pixbuf);
}
}
capture_cursor (screenshot, scale, x_orig, y_orig, width, height);
return screenshot;
}
......@@ -811,10 +826,11 @@ static gboolean cb_motion_notify (GtkWidget *widget,
static GdkPixbuf
*capture_rectangle_screenshot (gint x, gint y, gint w, gint h, gint delay)
*capture_rectangle_screenshot (gint x, gint y, gint w, gint h, gint delay, gboolean show_mouse)
{
GdkWindow *root;
int root_width, root_height;
GdkPixbuf *screenshot;
root = gdk_get_default_root_window ();
root_width = gdk_window_get_width (root);
......@@ -840,7 +856,12 @@ static GdkPixbuf
else
sleep (delay);
return gdk_pixbuf_get_from_window (root, x, y, w, h);
screenshot = gdk_pixbuf_get_from_window (root, x, y, w, h);
if (show_mouse)
capture_cursor (screenshot, gdk_window_get_scale_factor (root), x, y, w, h);
return screenshot;
}
......@@ -869,7 +890,7 @@ try_grab (GdkSeat *seat, GdkWindow *window, GdkCursor *cursor)
static GdkPixbuf
*get_rectangle_screenshot_composited (gint delay)
*get_rectangle_screenshot_composited (gint delay, gboolean show_mouse)
{
GtkWidget *window;
RubberBandData rbdata;
......@@ -963,7 +984,7 @@ static GdkPixbuf
rbdata.rectangle.y,
rbdata.rectangle.width,
rbdata.rectangle.height,
delay);
delay, show_mouse);
cleanup:
if (rbdata.size_window)
......@@ -1213,7 +1234,7 @@ region_filter_func (GdkXEvent *xevent, GdkEvent *event, RbData *rbdata)
static GdkPixbuf
*get_rectangle_screenshot (gint delay)
*get_rectangle_screenshot (gint delay, gboolean show_mouse)
{
GdkPixbuf *screenshot = NULL;
GdkWindow *root_window;
......@@ -1307,7 +1328,7 @@ static GdkPixbuf
rbdata.rectangle.y,
rbdata.rectangle.width,
rbdata.rectangle.height,
delay);
delay, show_mouse);
}
if (G_LIKELY (gc != NULL))
......@@ -1400,9 +1421,9 @@ G_GNUC_END_IGNORE_DEPRECATIONS
{
TRACE ("Let the user select the region to screenshot");
if (!gdk_screen_is_composited (screen))
screenshot = get_rectangle_screenshot (delay);
screenshot = get_rectangle_screenshot (delay, show_mouse);
else
screenshot = get_rectangle_screenshot_composited (delay);
screenshot = get_rectangle_screenshot_composited (delay, show_mouse);
}
return screenshot;
......
......@@ -44,9 +44,6 @@ static void
cb_toggle_set_sensi (GtkToggleButton *tb,
GtkWidget *widget);
static void
cb_toggle_set_insensi (GtkToggleButton *tb,
GtkWidget *widget);
static void
cb_open_toggled (GtkToggleButton *tb,
ScreenshotData *sd);
static void
......@@ -156,15 +153,6 @@ cb_toggle_set_sensi (GtkToggleButton *tb, GtkWidget *widget)
/* Set the widget active if the toggle button is inactive */
static void
cb_toggle_set_insensi (GtkToggleButton *tb, GtkWidget *widget)
{
gtk_widget_set_sensitive (widget, !gtk_toggle_button_get_active (tb));
}
static void cb_open_toggled (GtkToggleButton *tb, ScreenshotData *sd)
{
if (gtk_toggle_button_get_active (tb))
......@@ -816,7 +804,6 @@ GtkWidget *screenshooter_region_dialog_new (ScreenshotData *sd, gboolean plugin)
gtk_check_button_new_with_label (_("Capture the mouse pointer"));
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (show_mouse_checkbox),
(sd->show_mouse == 1));
gtk_widget_set_sensitive (show_mouse_checkbox, (sd->region != SELECT));
gtk_widget_set_tooltip_text (show_mouse_checkbox,
_("Display the mouse pointer on the screenshot"));
gtk_box_pack_start (GTK_BOX (area_box),
......@@ -824,8 +811,6 @@ GtkWidget *screenshooter_region_dialog_new (ScreenshotData *sd, gboolean plugin)
FALSE, 5);
g_signal_connect (G_OBJECT (show_mouse_checkbox), "toggled",
G_CALLBACK (cb_show_mouse_toggled), sd);
g_signal_connect (G_OBJECT (rectangle_button), "toggled",
G_CALLBACK (cb_toggle_set_insensi), show_mouse_checkbox);
/* Create the main box for the delay stuff */
delay_main_box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment