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 ...@@ -69,13 +69,20 @@ static GdkPixbuf *get_cursor_pixbuf (GdkDisplay *display
gint *cursory, gint *cursory,
gint *xhot, gint *xhot,
gint *yhot); 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, static GdkPixbuf *get_window_screenshot (GdkWindow *window,
gboolean show_mouse, gboolean show_mouse,
gboolean border); gboolean border);
static GdkFilterReturn region_filter_func (GdkXEvent *xevent, static GdkFilterReturn region_filter_func (GdkXEvent *xevent,
GdkEvent *event, GdkEvent *event,
RbData *rbdata); 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, static gboolean cb_key_pressed (GtkWidget *widget,
GdkEventKey *event, GdkEventKey *event,
RubberBandData *rbdata); RubberBandData *rbdata);
...@@ -94,14 +101,14 @@ static gboolean cb_button_released (GtkWidget *wid ...@@ -94,14 +101,14 @@ static gboolean cb_button_released (GtkWidget *wid
static gboolean cb_motion_notify (GtkWidget *widget, static gboolean cb_motion_notify (GtkWidget *widget,
GdkEventMotion *event, GdkEventMotion *event,
RubberBandData *rbdata); RubberBandData *rbdata);
static GdkPixbuf *get_rectangle_screenshot_composited (gint delay); static GdkPixbuf *get_rectangle_screenshot_composited (gint delay,
gboolean show_mouse);
/* Internals */ /* Internals */
static Window static Window
find_wm_window (Window xid) find_wm_window (Window xid)
{ {
...@@ -230,6 +237,66 @@ fallback: ...@@ -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 static GdkPixbuf
*get_window_screenshot (GdkWindow *window, *get_window_screenshot (GdkWindow *window,
gboolean show_mouse, gboolean show_mouse,
...@@ -399,59 +466,7 @@ static GdkPixbuf ...@@ -399,59 +466,7 @@ static GdkPixbuf
} }
if (show_mouse) if (show_mouse)
{ capture_cursor (screenshot, scale, x_orig, y_orig, width, height);
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);
}
}
return screenshot; return screenshot;
} }
...@@ -811,10 +826,11 @@ static gboolean cb_motion_notify (GtkWidget *widget, ...@@ -811,10 +826,11 @@ static gboolean cb_motion_notify (GtkWidget *widget,
static GdkPixbuf 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; GdkWindow *root;
int root_width, root_height; int root_width, root_height;
GdkPixbuf *screenshot;
root = gdk_get_default_root_window (); root = gdk_get_default_root_window ();
root_width = gdk_window_get_width (root); root_width = gdk_window_get_width (root);
...@@ -840,7 +856,12 @@ static GdkPixbuf ...@@ -840,7 +856,12 @@ static GdkPixbuf
else else
sleep (delay); 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) ...@@ -869,7 +890,7 @@ try_grab (GdkSeat *seat, GdkWindow *window, GdkCursor *cursor)
static GdkPixbuf static GdkPixbuf
*get_rectangle_screenshot_composited (gint delay) *get_rectangle_screenshot_composited (gint delay, gboolean show_mouse)
{ {
GtkWidget *window; GtkWidget *window;
RubberBandData rbdata; RubberBandData rbdata;
...@@ -963,7 +984,7 @@ static GdkPixbuf ...@@ -963,7 +984,7 @@ static GdkPixbuf
rbdata.rectangle.y, rbdata.rectangle.y,
rbdata.rectangle.width, rbdata.rectangle.width,
rbdata.rectangle.height, rbdata.rectangle.height,
delay); delay, show_mouse);
cleanup: cleanup:
if (rbdata.size_window) if (rbdata.size_window)
...@@ -1213,7 +1234,7 @@ region_filter_func (GdkXEvent *xevent, GdkEvent *event, RbData *rbdata) ...@@ -1213,7 +1234,7 @@ region_filter_func (GdkXEvent *xevent, GdkEvent *event, RbData *rbdata)
static GdkPixbuf static GdkPixbuf
*get_rectangle_screenshot (gint delay) *get_rectangle_screenshot (gint delay, gboolean show_mouse)
{ {
GdkPixbuf *screenshot = NULL; GdkPixbuf *screenshot = NULL;
GdkWindow *root_window; GdkWindow *root_window;
...@@ -1307,7 +1328,7 @@ static GdkPixbuf ...@@ -1307,7 +1328,7 @@ static GdkPixbuf
rbdata.rectangle.y, rbdata.rectangle.y,
rbdata.rectangle.width, rbdata.rectangle.width,
rbdata.rectangle.height, rbdata.rectangle.height,
delay); delay, show_mouse);
} }
if (G_LIKELY (gc != NULL)) if (G_LIKELY (gc != NULL))
...@@ -1400,9 +1421,9 @@ G_GNUC_END_IGNORE_DEPRECATIONS ...@@ -1400,9 +1421,9 @@ G_GNUC_END_IGNORE_DEPRECATIONS
{ {
TRACE ("Let the user select the region to screenshot"); TRACE ("Let the user select the region to screenshot");
if (!gdk_screen_is_composited (screen)) if (!gdk_screen_is_composited (screen))
screenshot = get_rectangle_screenshot (delay); screenshot = get_rectangle_screenshot (delay, show_mouse);
else else
screenshot = get_rectangle_screenshot_composited (delay); screenshot = get_rectangle_screenshot_composited (delay, show_mouse);
} }
return screenshot; return screenshot;
......
...@@ -44,9 +44,6 @@ static void ...@@ -44,9 +44,6 @@ static void
cb_toggle_set_sensi (GtkToggleButton *tb, cb_toggle_set_sensi (GtkToggleButton *tb,
GtkWidget *widget); GtkWidget *widget);
static void static void
cb_toggle_set_insensi (GtkToggleButton *tb,
GtkWidget *widget);
static void
cb_open_toggled (GtkToggleButton *tb, cb_open_toggled (GtkToggleButton *tb,
ScreenshotData *sd); ScreenshotData *sd);
static void static void
...@@ -156,15 +153,6 @@ cb_toggle_set_sensi (GtkToggleButton *tb, GtkWidget *widget) ...@@ -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) static void cb_open_toggled (GtkToggleButton *tb, ScreenshotData *sd)
{ {
if (gtk_toggle_button_get_active (tb)) if (gtk_toggle_button_get_active (tb))
...@@ -816,7 +804,6 @@ GtkWidget *screenshooter_region_dialog_new (ScreenshotData *sd, gboolean plugin) ...@@ -816,7 +804,6 @@ GtkWidget *screenshooter_region_dialog_new (ScreenshotData *sd, gboolean plugin)
gtk_check_button_new_with_label (_("Capture the mouse pointer")); gtk_check_button_new_with_label (_("Capture the mouse pointer"));
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (show_mouse_checkbox), gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (show_mouse_checkbox),
(sd->show_mouse == 1)); (sd->show_mouse == 1));
gtk_widget_set_sensitive (show_mouse_checkbox, (sd->region != SELECT));
gtk_widget_set_tooltip_text (show_mouse_checkbox, gtk_widget_set_tooltip_text (show_mouse_checkbox,
_("Display the mouse pointer on the screenshot")); _("Display the mouse pointer on the screenshot"));
gtk_box_pack_start (GTK_BOX (area_box), gtk_box_pack_start (GTK_BOX (area_box),
...@@ -824,8 +811,6 @@ GtkWidget *screenshooter_region_dialog_new (ScreenshotData *sd, gboolean plugin) ...@@ -824,8 +811,6 @@ GtkWidget *screenshooter_region_dialog_new (ScreenshotData *sd, gboolean plugin)
FALSE, 5); FALSE, 5);
g_signal_connect (G_OBJECT (show_mouse_checkbox), "toggled", g_signal_connect (G_OBJECT (show_mouse_checkbox), "toggled",
G_CALLBACK (cb_show_mouse_toggled), sd); 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 */ /* Create the main box for the delay stuff */
delay_main_box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6); 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