|
|
|
@ -76,8 +76,6 @@
|
|
|
|
|
#include <sys/time.h>
|
|
|
|
|
#include <sys/param.h>
|
|
|
|
|
|
|
|
|
|
#include "../libgtk/gtkpreview.h"
|
|
|
|
|
|
|
|
|
|
#include "gtkglue.h"
|
|
|
|
|
#include "preview.h"
|
|
|
|
|
#include "preferences.h"
|
|
|
|
@ -120,11 +118,6 @@
|
|
|
|
|
static void scan_start (Preview * p);
|
|
|
|
|
static void scan_done (Preview * p);
|
|
|
|
|
|
|
|
|
|
void preview_pixbuf_data_destroy(guchar* pixels, gpointer data) {
|
|
|
|
|
DBG(DBG_proc, "slider_pixbuf_data_destroy\n");
|
|
|
|
|
free(pixels);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
screen_size_get_dimensions (gint *width, gint *height)
|
|
|
|
|
{
|
|
|
|
@ -142,7 +135,7 @@ screen_size_get_dimensions (gint *width, gint *height)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
draw_rect(Preview *p, cairo_t *cr, double coord[4])
|
|
|
|
|
draw_rect(cairo_t *cr, double coord[4])
|
|
|
|
|
{
|
|
|
|
|
double x, y, w, h;
|
|
|
|
|
|
|
|
|
@ -177,33 +170,15 @@ draw_rect(Preview *p, cairo_t *cr, double coord[4])
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
draw_selection (Preview * p)
|
|
|
|
|
draw_selection (Preview * p, cairo_t *cr)
|
|
|
|
|
{
|
|
|
|
|
cairo_surface_t *surface = NULL;
|
|
|
|
|
cairo_t *cr = NULL;
|
|
|
|
|
GdkWindow *window = NULL;
|
|
|
|
|
if (!p->window)
|
|
|
|
|
/* window isn't mapped yet */
|
|
|
|
|
return;
|
|
|
|
|
window = gtk_widget_get_window(p->window);
|
|
|
|
|
if (window == NULL) return;
|
|
|
|
|
surface = gdk_window_create_similar_surface (
|
|
|
|
|
window,
|
|
|
|
|
CAIRO_CONTENT_COLOR,
|
|
|
|
|
gdk_window_get_width(window),
|
|
|
|
|
gdk_window_get_height(window));
|
|
|
|
|
if (surface == NULL) return;
|
|
|
|
|
cr = cairo_create(surface);
|
|
|
|
|
if (cr == NULL) return;
|
|
|
|
|
if (p->previous_selection.active)
|
|
|
|
|
draw_rect (p, cr, p->previous_selection.coord);
|
|
|
|
|
draw_rect (cr, p->previous_selection.coord);
|
|
|
|
|
|
|
|
|
|
if (p->selection.active)
|
|
|
|
|
draw_rect (p, cr, p->selection.coord);
|
|
|
|
|
draw_rect (cr, p->selection.coord);
|
|
|
|
|
|
|
|
|
|
p->previous_selection = p->selection;
|
|
|
|
|
|
|
|
|
|
cairo_destroy(cr);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
@ -252,7 +227,6 @@ update_selection (Preview * p)
|
|
|
|
|
if (p->selection.coord[i + 2] < p->selection.coord[i])
|
|
|
|
|
p->selection.coord[i + 2] = p->selection.coord[i];
|
|
|
|
|
}
|
|
|
|
|
draw_selection (p);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
@ -334,10 +308,10 @@ paint_image (Preview * p)
|
|
|
|
|
p->image_data[src_offset + 3 * x + 2];
|
|
|
|
|
src_x += xscale;
|
|
|
|
|
}
|
|
|
|
|
gtk_preview_draw_row (GTK_PREVIEW (p->window), p->preview_row,
|
|
|
|
|
0, dst_y, gwidth);
|
|
|
|
|
memcpy(p->preview_data + (size_t) dst_y * (size_t) gwidth * 3, p->preview_row, (size_t) gwidth * 3);
|
|
|
|
|
src_x = 0.0;
|
|
|
|
|
src_y += yscale;
|
|
|
|
|
gtk_widget_queue_draw (p->window);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -347,35 +321,6 @@ display_partial_image (Preview * p)
|
|
|
|
|
DBG(DBG_proc, "preview_display_partial_image\n");
|
|
|
|
|
|
|
|
|
|
paint_image(p);
|
|
|
|
|
|
|
|
|
|
if (gtk_widget_is_drawable(p->window))
|
|
|
|
|
{
|
|
|
|
|
cairo_surface_t *surface = NULL;
|
|
|
|
|
cairo_t *cr = NULL;
|
|
|
|
|
GdkWindow *window = NULL;
|
|
|
|
|
int src_x, src_y;
|
|
|
|
|
GtkAllocation alloc;
|
|
|
|
|
gtk_widget_get_allocated_size (p->window, &alloc, NULL);
|
|
|
|
|
|
|
|
|
|
GtkPreview *preview = GTK_PREVIEW (p->window);
|
|
|
|
|
|
|
|
|
|
window = gtk_widget_get_window(p->window);
|
|
|
|
|
surface = gdk_window_create_similar_surface (
|
|
|
|
|
window,
|
|
|
|
|
CAIRO_CONTENT_COLOR,
|
|
|
|
|
gdk_window_get_width(window),
|
|
|
|
|
gdk_window_get_height(window));
|
|
|
|
|
cr = cairo_create(surface);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
src_x = (alloc.width - preview->buffer_width) / 2;
|
|
|
|
|
src_y = (alloc.height - preview->buffer_height) / 2;
|
|
|
|
|
gtk_preview_put (preview, cr,
|
|
|
|
|
src_x, src_y,
|
|
|
|
|
0, 0, p->preview_width, p->preview_height);
|
|
|
|
|
cairo_destroy(cr);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
@ -394,26 +339,25 @@ display_maybe (Preview * p)
|
|
|
|
|
static void
|
|
|
|
|
display_image (Preview * p)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
if (p->params.lines <= 0 && p->image_y < p->image_height)
|
|
|
|
|
{
|
|
|
|
|
p->image_height = p->image_y;
|
|
|
|
|
p->image_data = realloc (p->image_data,
|
|
|
|
|
3 * p->image_width * p->image_height);
|
|
|
|
|
assert (p->image_data);
|
|
|
|
|
p->preview_data = realloc (p->preview_data,
|
|
|
|
|
3 * p->image_width * p->image_height);
|
|
|
|
|
}
|
|
|
|
|
display_partial_image (p);
|
|
|
|
|
scan_done (p);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
preview_area_resize (GtkWidget * widget)
|
|
|
|
|
preview_area_resize (GtkWidget * widget, GdkEvent *event, gpointer data)
|
|
|
|
|
{
|
|
|
|
|
float min_x, max_x, min_y, max_y, xscale, yscale, f;
|
|
|
|
|
GtkAllocation alloc;
|
|
|
|
|
Preview *p = NULL;
|
|
|
|
|
|
|
|
|
|
p = g_object_get_data (G_OBJECT (widget), "PreviewPointer");
|
|
|
|
|
Preview *p = data;
|
|
|
|
|
|
|
|
|
|
gtk_widget_get_allocated_size (widget, &alloc, NULL);
|
|
|
|
|
|
|
|
|
@ -425,7 +369,7 @@ preview_area_resize (GtkWidget * widget)
|
|
|
|
|
else
|
|
|
|
|
p->preview_row = malloc (3 * p->preview_width);
|
|
|
|
|
|
|
|
|
|
// set the ruler ranges:
|
|
|
|
|
/* set the ruler ranges: */
|
|
|
|
|
|
|
|
|
|
min_x = p->surface[GSG_TL_X];
|
|
|
|
|
if (min_x <= -INF)
|
|
|
|
@ -443,7 +387,7 @@ preview_area_resize (GtkWidget * widget)
|
|
|
|
|
if (max_y >= INF)
|
|
|
|
|
max_y = p->preview_height - 1;
|
|
|
|
|
|
|
|
|
|
// convert mm to inches if that's what the user wants:
|
|
|
|
|
/* convert mm to inches if that's what the user wants: */
|
|
|
|
|
|
|
|
|
|
if (p->surface_unit == SANE_UNIT_MM)
|
|
|
|
|
{
|
|
|
|
@ -482,8 +426,8 @@ preview_area_resize (GtkWidget * widget)
|
|
|
|
|
// f * min_y,
|
|
|
|
|
20); // max_size
|
|
|
|
|
|
|
|
|
|
paint_image (p);
|
|
|
|
|
update_selection (p);
|
|
|
|
|
paint_image (p);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
@ -537,12 +481,8 @@ save_option (Preview * p, int option, SANE_Word * save_loc, int *valid)
|
|
|
|
|
*valid = 0;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
status = sane_control_option (
|
|
|
|
|
p->dialog->dev,
|
|
|
|
|
option,
|
|
|
|
|
SANE_ACTION_GET_VALUE,
|
|
|
|
|
save_loc,
|
|
|
|
|
0);
|
|
|
|
|
status = sane_control_option (p->dialog->dev, option, SANE_ACTION_GET_VALUE,
|
|
|
|
|
save_loc, 0);
|
|
|
|
|
*valid = (status == SANE_STATUS_GOOD);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -633,6 +573,7 @@ increment_image_y (Preview * p)
|
|
|
|
|
extra_size = 3 * 32 * p->image_width;
|
|
|
|
|
p->image_height += 32;
|
|
|
|
|
p->image_data = realloc (p->image_data, offset + extra_size);
|
|
|
|
|
p->preview_data = realloc (p->preview_data, offset + extra_size);
|
|
|
|
|
if (!p->image_data)
|
|
|
|
|
{
|
|
|
|
|
snprintf (buf, sizeof (buf),
|
|
|
|
@ -643,6 +584,7 @@ increment_image_y (Preview * p)
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
memset (p->image_data + offset, 0xff, extra_size);
|
|
|
|
|
memset (p->preview_data + offset, 0xff, extra_size);
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
@ -701,7 +643,7 @@ input_available (gpointer data, gint source, GIOCondition cond)
|
|
|
|
|
scan_done (p);
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
if (!len) // out of data for now
|
|
|
|
|
if (!len) /* out of data for now */
|
|
|
|
|
{
|
|
|
|
|
if (p->input_tag < 0)
|
|
|
|
|
{
|
|
|
|
@ -802,7 +744,7 @@ input_available (gpointer data, gint source, GIOCondition cond)
|
|
|
|
|
{
|
|
|
|
|
if (increment_image_y (p) < 0)
|
|
|
|
|
return FALSE;
|
|
|
|
|
break; // skip padding bits
|
|
|
|
|
break; /* skip padding bits */
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -917,6 +859,7 @@ input_available (gpointer data, gint source, GIOCondition cond)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
display_maybe (p);
|
|
|
|
|
p->scanning = FALSE;
|
|
|
|
|
return TRUE;
|
|
|
|
|
|
|
|
|
|
bad_depth:
|
|
|
|
@ -963,18 +906,21 @@ scan_start (Preview * p)
|
|
|
|
|
SANE_Handle dev = p->dialog->dev;
|
|
|
|
|
SANE_Status status;
|
|
|
|
|
char buf[256];
|
|
|
|
|
int fd, y;
|
|
|
|
|
int fd;
|
|
|
|
|
Progress_t *progress;
|
|
|
|
|
#ifdef HAVE_SYS_TIME_H
|
|
|
|
|
struct timeval start, current;
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
p->scanning = TRUE;
|
|
|
|
|
gtk_widget_set_sensitive (p->cancel, TRUE);
|
|
|
|
|
gtk_widget_set_sensitive (p->preview, FALSE);
|
|
|
|
|
gsg_set_sensitivity (p->dialog, FALSE);
|
|
|
|
|
// gtk_widget_set_sensitive (p->dialog->window->parent->parent->parent, FALSE);
|
|
|
|
|
|
|
|
|
|
/* clear old preview: */
|
|
|
|
|
memset (p->preview_row, 0xff, 3 * p->preview_width);
|
|
|
|
|
for (y = 0; y < p->preview_height; ++y)
|
|
|
|
|
gtk_preview_draw_row (GTK_PREVIEW (p->window), p->preview_row,
|
|
|
|
|
0, y, p->preview_width);
|
|
|
|
|
memset (p->preview_data, 0xff, 3 * p->image_width * p->image_height);
|
|
|
|
|
gtk_widget_queue_draw (p->window);
|
|
|
|
|
|
|
|
|
|
if (p->input_tag >= 0)
|
|
|
|
|
{
|
|
|
|
@ -1005,7 +951,7 @@ scan_start (Preview * p)
|
|
|
|
|
|
|
|
|
|
# ifdef HAVE_SYS_TIME_H
|
|
|
|
|
gettimeofday (¤t, NULL);
|
|
|
|
|
// we assume that warming up won't exceed 60 seconds
|
|
|
|
|
/* we assume that warming up won't exceed 60 seconds */
|
|
|
|
|
progress_update (progress,
|
|
|
|
|
(current.tv_sec - start.tv_sec) / (gfloat) 60);
|
|
|
|
|
# endif
|
|
|
|
@ -1019,7 +965,7 @@ scan_start (Preview * p)
|
|
|
|
|
}
|
|
|
|
|
progress_free (progress);
|
|
|
|
|
}
|
|
|
|
|
#endif // SANE_STATUS_WARMING_UP
|
|
|
|
|
#endif /* SANE_STATUS_WARMING_UP */
|
|
|
|
|
if (status != SANE_STATUS_GOOD)
|
|
|
|
|
{
|
|
|
|
|
snprintf (buf, sizeof (buf),
|
|
|
|
@ -1059,16 +1005,17 @@ scan_start (Preview * p)
|
|
|
|
|
if (!p->image_data || p->params.pixels_per_line != p->image_width
|
|
|
|
|
|| (p->params.lines >= 0 && p->params.lines != p->image_height))
|
|
|
|
|
{
|
|
|
|
|
// image size changed
|
|
|
|
|
/* image size changed */
|
|
|
|
|
if (p->image_data)
|
|
|
|
|
free (p->image_data);
|
|
|
|
|
|
|
|
|
|
p->image_width = p->params.pixels_per_line;
|
|
|
|
|
p->image_height = p->params.lines;
|
|
|
|
|
if (p->image_height < 0)
|
|
|
|
|
p->image_height = 32; // may have to adjust as we go...
|
|
|
|
|
p->image_height = 32; /* may have to adjust as we go... */
|
|
|
|
|
|
|
|
|
|
p->image_data = malloc (p->image_width * p->image_height * 3);
|
|
|
|
|
p->preview_data = malloc (p->preview_width * p->image_height * 3);
|
|
|
|
|
if (!p->image_data)
|
|
|
|
|
{
|
|
|
|
|
snprintf (buf, sizeof (buf),
|
|
|
|
@ -1084,7 +1031,7 @@ scan_start (Preview * p)
|
|
|
|
|
{
|
|
|
|
|
p->previous_selection = p->selection;
|
|
|
|
|
p->selection.active = FALSE;
|
|
|
|
|
draw_selection (p);
|
|
|
|
|
gtk_widget_queue_draw (p->window);
|
|
|
|
|
}
|
|
|
|
|
p->scanning = TRUE;
|
|
|
|
|
|
|
|
|
@ -1149,7 +1096,7 @@ restore_preview_image (Preview * p)
|
|
|
|
|
size_t nread;
|
|
|
|
|
FILE *in;
|
|
|
|
|
|
|
|
|
|
// See whether there is a saved preview and load it if present:
|
|
|
|
|
/* See whether there is a saved preview and load it if present: */
|
|
|
|
|
|
|
|
|
|
if (make_preview_image_path (p, sizeof (filename), filename) < 0)
|
|
|
|
|
return;
|
|
|
|
@ -1158,8 +1105,8 @@ restore_preview_image (Preview * p)
|
|
|
|
|
if (!in)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
// Be careful about consuming too many bytes after the final newline
|
|
|
|
|
// (e.g., consider an image whose first image byte is 13 (`\r').
|
|
|
|
|
/* Be careful about consuming too many bytes after the final newline
|
|
|
|
|
(e.g., consider an image whose first image byte is 13 (`\r'). */
|
|
|
|
|
if (fscanf (in, "P6\n# surface: %g %g %g %g %u %u\n%d %d\n255%*[\n]",
|
|
|
|
|
psurface + 0, psurface + 1, psurface + 2, psurface + 3,
|
|
|
|
|
&psurface_type, &psurface_unit, &width, &height) != 8)
|
|
|
|
@ -1170,7 +1117,7 @@ restore_preview_image (Preview * p)
|
|
|
|
|
|| GROSSLY_DIFFERENT (psurface[2], p->surface[2])
|
|
|
|
|
|| GROSSLY_DIFFERENT (psurface[3], p->surface[3])
|
|
|
|
|
|| psurface_type != p->surface_type || psurface_unit != p->surface_unit)
|
|
|
|
|
// ignore preview image that was acquired for/with a different surface
|
|
|
|
|
/* ignore preview image that was acquired for/with a different surface */
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
p->image_width = width;
|
|
|
|
@ -1178,6 +1125,7 @@ restore_preview_image (Preview * p)
|
|
|
|
|
if ((width == 0) || (height == 0))
|
|
|
|
|
return;
|
|
|
|
|
p->image_data = malloc (3 * width * height);
|
|
|
|
|
p->preview_data = malloc (3 * width * height);
|
|
|
|
|
if (!p->image_data)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
@ -1187,14 +1135,24 @@ restore_preview_image (Preview * p)
|
|
|
|
|
p->image_x = nread % width;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// This is executed _after_ the gtkpreview's expose routine.
|
|
|
|
|
/* This is executed _after_ the gtkpreview's expose routine. */
|
|
|
|
|
static gint
|
|
|
|
|
expose_handler (GtkWidget * window, cairo_t *cr, gpointer data)
|
|
|
|
|
{
|
|
|
|
|
Preview *p = data;
|
|
|
|
|
|
|
|
|
|
if (p->preview_data == NULL) return FALSE;
|
|
|
|
|
|
|
|
|
|
GdkPixbuf* pixbuf = gdk_pixbuf_new_from_data(p->preview_data, GDK_COLORSPACE_RGB, FALSE, 8, p->preview_width,
|
|
|
|
|
p->preview_height, p->preview_width * 3, NULL/*preview_pixbuf_data_destroy*/, NULL);
|
|
|
|
|
gdk_cairo_set_source_pixbuf (cr, pixbuf, 0, 0);
|
|
|
|
|
cairo_paint(cr);
|
|
|
|
|
g_object_unref(pixbuf);
|
|
|
|
|
|
|
|
|
|
// => update_selection (p);
|
|
|
|
|
draw_selection (p, cr);
|
|
|
|
|
|
|
|
|
|
p->selection.active = FALSE;
|
|
|
|
|
update_selection (p);
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -1203,7 +1161,6 @@ button_press_handler(GtkWidget *window,
|
|
|
|
|
GdkEvent *event, gpointer data)
|
|
|
|
|
{
|
|
|
|
|
Preview *p = data;
|
|
|
|
|
|
|
|
|
|
if (p->scanning)
|
|
|
|
|
return FALSE;
|
|
|
|
|
p->selection.coord[0] = event->button.x;
|
|
|
|
@ -1219,7 +1176,9 @@ button_release_handler (GtkWidget *window,
|
|
|
|
|
Preview *p = data;
|
|
|
|
|
int i, tmp;
|
|
|
|
|
|
|
|
|
|
if (p->scanning || !p->selection_drag)
|
|
|
|
|
if (p->scanning == TRUE)
|
|
|
|
|
return FALSE;
|
|
|
|
|
if (p->selection_drag == FALSE)
|
|
|
|
|
return FALSE;
|
|
|
|
|
p->selection_drag = FALSE;
|
|
|
|
|
|
|
|
|
@ -1247,7 +1206,7 @@ button_release_handler (GtkWidget *window,
|
|
|
|
|
if (p->selection.coord[3] >= p->preview_height)
|
|
|
|
|
p->selection.coord[3] = p->preview_height - 1;
|
|
|
|
|
}
|
|
|
|
|
draw_selection (p);
|
|
|
|
|
gtk_widget_queue_draw (p->window);
|
|
|
|
|
establish_selection (p);
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
@ -1257,37 +1216,17 @@ motion_handler (GtkWidget *window,
|
|
|
|
|
GdkEvent *event, gpointer data)
|
|
|
|
|
{
|
|
|
|
|
Preview *p = data;
|
|
|
|
|
if (!p->scanning || p->selection_drag)
|
|
|
|
|
if (p->scanning == TRUE) return FALSE;
|
|
|
|
|
if (p->selection_drag == TRUE)
|
|
|
|
|
{
|
|
|
|
|
p->selection.active = TRUE;
|
|
|
|
|
p->selection.coord[2] = event->motion.x;
|
|
|
|
|
p->selection.coord[3] = event->motion.y;
|
|
|
|
|
draw_selection (p);
|
|
|
|
|
gtk_widget_queue_draw (p->window);
|
|
|
|
|
}
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static gint
|
|
|
|
|
event_handler (GtkWidget * window, GdkEvent * event, gpointer data)
|
|
|
|
|
{
|
|
|
|
|
Preview *p = data;
|
|
|
|
|
|
|
|
|
|
if (event->type == GDK_EXPOSE)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
if (gtk_widget_is_drawable(GTK_WIDGET(p->window)))
|
|
|
|
|
{
|
|
|
|
|
paint_image (p);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
p->selection.active = FALSE;
|
|
|
|
|
draw_selection (p);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
start_button_clicked (GtkWidget * widget, gpointer data)
|
|
|
|
|
{
|
|
|
|
@ -1314,7 +1253,6 @@ preview_new (GSGDialog * dialog)
|
|
|
|
|
static int first_time = 1;
|
|
|
|
|
GtkWidget *table, *frame;
|
|
|
|
|
GCallback signal_func;
|
|
|
|
|
GtkWidgetClass *class;
|
|
|
|
|
GtkBox *vbox;
|
|
|
|
|
Preview *p;
|
|
|
|
|
|
|
|
|
@ -1322,10 +1260,15 @@ preview_new (GSGDialog * dialog)
|
|
|
|
|
if (!p)
|
|
|
|
|
return 0;
|
|
|
|
|
memset (p, 0, sizeof (*p));
|
|
|
|
|
// printf ("%d) (%s) DEV NAME [%s]\n",__LINE__, __FILE__, dialog->dev_name); fflush(stdout);
|
|
|
|
|
|
|
|
|
|
p->dialog = dialog;
|
|
|
|
|
p->surface_unit = SANE_UNIT_MM;
|
|
|
|
|
p->input_tag = -1;
|
|
|
|
|
p->image_data = NULL;
|
|
|
|
|
p->preview_data = NULL;
|
|
|
|
|
p->preview_row = NULL;
|
|
|
|
|
p->top = NULL;
|
|
|
|
|
p->scanning = FALSE;
|
|
|
|
|
|
|
|
|
|
if (first_time)
|
|
|
|
|
{
|
|
|
|
@ -1347,37 +1290,33 @@ preview_new (GSGDialog * dialog)
|
|
|
|
|
gtk_container_set_border_width (GTK_CONTAINER (table), 2);
|
|
|
|
|
gtk_box_pack_start (vbox, table, TRUE, TRUE, 0);
|
|
|
|
|
|
|
|
|
|
// the empty box in the top-left corner
|
|
|
|
|
frame = gtk_frame_new ( 0);
|
|
|
|
|
/* the empty box in the top-left corner */
|
|
|
|
|
frame = gtk_frame_new ( /* label */ 0);
|
|
|
|
|
gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_OUT);
|
|
|
|
|
gtk_grid_attach (GTK_GRID (table), frame, 0, 0, 1, 1);
|
|
|
|
|
|
|
|
|
|
// the horizontal ruler
|
|
|
|
|
/* the horizontal ruler */
|
|
|
|
|
p->hruler = gimp_gtk3_ruler_new (GTK_ORIENTATION_HORIZONTAL);
|
|
|
|
|
gtk_widget_set_margin_top (GTK_WIDGET(p->hruler), 0);
|
|
|
|
|
gtk_widget_set_vexpand(GTK_WIDGET(p->hruler), FALSE);
|
|
|
|
|
gtk_grid_attach (GTK_GRID (table), p->hruler, 1, 0, 1, 1);
|
|
|
|
|
gsg_widget_placement(GTK_WIDGET (p->hruler), GTK_ALIGN_FILL, GTK_ALIGN_CENTER, 0, 0, 0, 0);
|
|
|
|
|
|
|
|
|
|
// the vertical ruler
|
|
|
|
|
/* the vertical ruler */
|
|
|
|
|
p->vruler = gimp_gtk3_ruler_new (GTK_ORIENTATION_VERTICAL);
|
|
|
|
|
gtk_widget_set_margin_start (GTK_WIDGET(p->vruler), 0);
|
|
|
|
|
gtk_widget_set_margin_end (GTK_WIDGET(p->vruler), 0);
|
|
|
|
|
gtk_widget_set_hexpand(GTK_WIDGET(p->vruler), FALSE);
|
|
|
|
|
gtk_grid_attach (GTK_GRID (table), p->vruler, 0, 1, 1, 1);
|
|
|
|
|
gsg_widget_placement(GTK_WIDGET (p->vruler), GTK_ALIGN_CENTER, GTK_ALIGN_FILL, 0, 0, 0, 0);
|
|
|
|
|
|
|
|
|
|
/* the preview area */
|
|
|
|
|
p->window = gtk_drawing_area_new ();
|
|
|
|
|
gtk_widget_set_app_paintable(p->window, TRUE);
|
|
|
|
|
gsg_widget_placement(GTK_WIDGET (p->window), GTK_ALIGN_FILL, GTK_ALIGN_FILL, 0, 0, 0, 0);
|
|
|
|
|
|
|
|
|
|
p->window = gtk_preview_new (GTK_PREVIEW_COLOR);
|
|
|
|
|
gtk_widget_set_vexpand(GTK_WIDGET(p->window), TRUE);
|
|
|
|
|
gtk_widget_set_hexpand(GTK_WIDGET(p->window), TRUE);
|
|
|
|
|
gtk_preview_set_expand (GTK_PREVIEW (p->window), TRUE);
|
|
|
|
|
gtk_widget_set_events (p->window,
|
|
|
|
|
GDK_EXPOSURE_MASK |
|
|
|
|
|
GDK_POINTER_MOTION_MASK |
|
|
|
|
|
GDK_POINTER_MOTION_HINT_MASK |
|
|
|
|
|
GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK);
|
|
|
|
|
g_signal_connect (G_OBJECT (p->window), "event",
|
|
|
|
|
G_CALLBACK(event_handler), p);
|
|
|
|
|
GDK_BUTTON_PRESS_MASK |
|
|
|
|
|
GDK_BUTTON_RELEASE_MASK);
|
|
|
|
|
|
|
|
|
|
g_signal_connect_after (G_OBJECT (p->window), "draw",
|
|
|
|
|
G_CALLBACK(expose_handler), p);
|
|
|
|
|
|
|
|
|
@ -1387,41 +1326,37 @@ preview_new (GSGDialog * dialog)
|
|
|
|
|
G_CALLBACK(motion_handler), p);
|
|
|
|
|
g_signal_connect(G_OBJECT(p->window), "button_release_event",
|
|
|
|
|
G_CALLBACK(button_release_handler), p);
|
|
|
|
|
|
|
|
|
|
g_signal_connect_after (G_OBJECT (p->window), "size_allocate",
|
|
|
|
|
G_CALLBACK(preview_area_resize), 0);
|
|
|
|
|
g_object_set_data (G_OBJECT (p->window), "PreviewPointer", p);
|
|
|
|
|
G_CALLBACK(preview_area_resize), p);
|
|
|
|
|
|
|
|
|
|
g_object_set_data (G_OBJECT (p->window), "PreviewPointer", p);
|
|
|
|
|
|
|
|
|
|
class = GTK_WIDGET_CLASS (GIMP_GTK3_RULER_GET_CLASS (p->hruler));
|
|
|
|
|
signal_func = G_CALLBACK (class->motion_notify_event);
|
|
|
|
|
signal_func = G_CALLBACK (gimp_gtk3_ruler_motion);
|
|
|
|
|
g_signal_connect (G_OBJECT (p->window), "motion_notify_event",
|
|
|
|
|
signal_func, G_OBJECT (p->hruler));
|
|
|
|
|
|
|
|
|
|
class = GTK_WIDGET_CLASS (GIMP_GTK3_RULER_GET_CLASS (p->vruler));
|
|
|
|
|
signal_func = G_CALLBACK (class->motion_notify_event);
|
|
|
|
|
signal_func = G_CALLBACK (gimp_gtk3_ruler_motion);
|
|
|
|
|
g_signal_connect (G_OBJECT (p->window), "motion_notify_event",
|
|
|
|
|
signal_func, G_OBJECT (p->vruler));
|
|
|
|
|
|
|
|
|
|
// preview_area_resize (GTK_WIDGET (p->window), NULL);
|
|
|
|
|
p->viewport = gtk_frame_new ( 0);
|
|
|
|
|
gtk_frame_set_shadow_type (GTK_FRAME (p->viewport), GTK_SHADOW_IN);
|
|
|
|
|
gtk_container_add (GTK_CONTAINER (p->viewport), p->window);
|
|
|
|
|
|
|
|
|
|
gtk_grid_attach (GTK_GRID (table), p->viewport, 1, 1, 1, 1);
|
|
|
|
|
gsg_widget_placement(GTK_WIDGET (p->viewport), GTK_ALIGN_FILL, GTK_ALIGN_FILL, 0, 0, 0, 0);
|
|
|
|
|
gtk_widget_set_vexpand (GTK_WIDGET (p->viewport),TRUE);
|
|
|
|
|
gtk_widget_set_hexpand (GTK_WIDGET (p->viewport),TRUE);
|
|
|
|
|
|
|
|
|
|
preview_update (p);
|
|
|
|
|
|
|
|
|
|
// fill in action area:
|
|
|
|
|
/* fill in action area: */
|
|
|
|
|
|
|
|
|
|
// Preview button
|
|
|
|
|
/* Preview button */
|
|
|
|
|
p->preview = gtk_dialog_add_button (GTK_DIALOG (p->top), "Acquire Preview",GTK_RESPONSE_OK);
|
|
|
|
|
g_signal_connect (G_OBJECT (p->preview), "clicked",
|
|
|
|
|
G_CALLBACK (start_button_clicked), p);
|
|
|
|
|
gtk_widget_show (p->preview);
|
|
|
|
|
|
|
|
|
|
// Cancel button
|
|
|
|
|
/* Cancel button */
|
|
|
|
|
p->cancel = gtk_dialog_add_button (GTK_DIALOG (p->top), "Cancel Preview", GTK_RESPONSE_CANCEL);
|
|
|
|
|
g_signal_connect (G_OBJECT (p->cancel), "clicked",
|
|
|
|
|
G_CALLBACK (cancel_button_clicked), p);
|
|
|
|
@ -1488,12 +1423,14 @@ preview_update (Preview * p)
|
|
|
|
|
if (surface_changed && p->image_data)
|
|
|
|
|
{
|
|
|
|
|
free (p->image_data);
|
|
|
|
|
free (p->preview_data);
|
|
|
|
|
p->image_data = 0;
|
|
|
|
|
p->preview_data = 0;
|
|
|
|
|
p->image_width = 0;
|
|
|
|
|
p->image_height = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// guess the initial preview window size:
|
|
|
|
|
/* guess the initial preview window size: */
|
|
|
|
|
|
|
|
|
|
width = p->surface[GSG_BR_X] - p->surface[GSG_TL_X];
|
|
|
|
|
height = p->surface[GSG_BR_Y] - p->surface[GSG_TL_Y];
|
|
|
|
@ -1550,7 +1487,7 @@ preview_update (Preview * p)
|
|
|
|
|
height = max_height;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// re-adjust so we maintain aspect without exceeding max size:
|
|
|
|
|
/* re-adjust so we maintain aspect without exceeding max size: */
|
|
|
|
|
if (width / height != p->aspect)
|
|
|
|
|
{
|
|
|
|
|
if (p->aspect > 1.0)
|
|
|
|
@ -1566,7 +1503,7 @@ preview_update (Preview * p)
|
|
|
|
|
gtk_widget_set_size_request (GTK_WIDGET (p->window),
|
|
|
|
|
p->preview_width, p->preview_height);
|
|
|
|
|
if (gtk_widget_is_drawable(GTK_WIDGET(p->window)))
|
|
|
|
|
preview_area_resize (p->window);
|
|
|
|
|
preview_area_resize (p->window, NULL, p);
|
|
|
|
|
|
|
|
|
|
if (preferences.preserve_preview)
|
|
|
|
|
restore_preview_image (p);
|
|
|
|
@ -1590,7 +1527,7 @@ preview_scan (Preview * p)
|
|
|
|
|
save_option (p, p->dialog->well_known.coord[i],
|
|
|
|
|
&p->saved_coord[i], p->saved_coord_valid + i);
|
|
|
|
|
|
|
|
|
|
// determine dpi, if necessary:
|
|
|
|
|
/* determine dpi, if necessary: */
|
|
|
|
|
|
|
|
|
|
if (p->dialog->well_known.dpi > 0)
|
|
|
|
|
{
|
|
|
|
@ -1629,13 +1566,13 @@ preview_scan (Preview * p)
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// set the scan window (necessary since backends may default to
|
|
|
|
|
// non-maximum size):
|
|
|
|
|
/* set the scan window (necessary since backends may default to
|
|
|
|
|
non-maximum size): */
|
|
|
|
|
for (i = 0; i < 4; ++i)
|
|
|
|
|
set_option_float (p, p->dialog->well_known.coord[i], p->surface[i]);
|
|
|
|
|
set_option_bool (p, p->dialog->well_known.preview, SANE_TRUE);
|
|
|
|
|
|
|
|
|
|
// OK, all set to go
|
|
|
|
|
/* OK, all set to go */
|
|
|
|
|
scan_start (p);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -1646,15 +1583,15 @@ preview_destroy (Preview * p)
|
|
|
|
|
FILE *out;
|
|
|
|
|
|
|
|
|
|
if (p->scanning)
|
|
|
|
|
scan_done (p); // don't save partial window
|
|
|
|
|
scan_done (p); /* don't save partial window */
|
|
|
|
|
else if (preferences.preserve_preview && p->image_data
|
|
|
|
|
&& make_preview_image_path (p, sizeof (filename), filename) >= 0)
|
|
|
|
|
{
|
|
|
|
|
// save preview image
|
|
|
|
|
/* save preview image */
|
|
|
|
|
out = fopen (filename, "w");
|
|
|
|
|
if (out)
|
|
|
|
|
{
|
|
|
|
|
// always save it as a PPM image:
|
|
|
|
|
/* always save it as a PPM image: */
|
|
|
|
|
fprintf (out, "P6\n# surface: %g %g %g %g %u %u\n%d %d\n255\n",
|
|
|
|
|
p->surface[0], p->surface[1], p->surface[2], p->surface[3],
|
|
|
|
|
p->surface_type, p->surface_unit,
|
|
|
|
@ -1665,8 +1602,13 @@ preview_destroy (Preview * p)
|
|
|
|
|
}
|
|
|
|
|
if (p->image_data)
|
|
|
|
|
free (p->image_data);
|
|
|
|
|
p->image_data = NULL;
|
|
|
|
|
if (p->preview_data)
|
|
|
|
|
free (p->preview_data);
|
|
|
|
|
p->preview_data = NULL;
|
|
|
|
|
if (p->preview_row)
|
|
|
|
|
free (p->preview_row);
|
|
|
|
|
p->preview_row = NULL;
|
|
|
|
|
if (p->top)
|
|
|
|
|
gtk_widget_destroy (p->top);
|
|
|
|
|
free (p);
|
|
|
|
|