gnome-scan r658 - in trunk: . modules
- From: bersace svn gnome org
- To: svn-commits-list gnome org
- Subject: gnome-scan r658 - in trunk: . modules
- Date: Thu, 11 Dec 2008 21:21:11 +0000 (UTC)
Author: bersace
Date: Thu Dec 11 21:21:11 2008
New Revision: 658
URL: http://svn.gnome.org/viewvc/gnome-scan?rev=658&view=rev
Log:
Preliminary rewrite of GSane.
Added:
trunk/modules/gsane-option-handler.c
trunk/modules/gsane-option-handler.h
trunk/modules/gsane-option-manager.c
trunk/modules/gsane-option-manager.h
Removed:
trunk/modules/gsane-meta-param.c
trunk/modules/gsane-meta-param.h
trunk/modules/gsfile-module.h
trunk/modules/gsfile-pspec.c
trunk/modules/gsfile-pspec.h
Modified:
trunk/ChangeLog
trunk/modules/Makefile.am
trunk/modules/gsane-backend.c
trunk/modules/gsane-common.c
trunk/modules/gsane-common.h
trunk/modules/gsane-module.c
trunk/modules/gsane-scanner.c
trunk/modules/gsane-scanner.h
Modified: trunk/modules/Makefile.am
==============================================================================
--- trunk/modules/Makefile.am (original)
+++ trunk/modules/Makefile.am Thu Dec 11 21:21:11 2008
@@ -7,16 +7,15 @@
modulesdir = @MODULE_DIR@
modules_LTLIBRARIES = \
- libgsfiles.la \
+ libgsfiles.la \
+ libgsane.la \
$(NULL)
-# libgsane.la
libgsfiles_la_SOURCES = \
gsfile-scanner.h \
gsfile-scanner.c \
gsfile-module.c \
- gsfile-module.h \
gsfile-backend.h \
gsfile-backend.c \
gsfile-options.h \
@@ -27,26 +26,31 @@
libgsfiles_la_LDFLAGS = -avoid-version -module
-# libgsane_la_SOURCES = \
-# gsane-backend.h \
-# gsane-backend.c \
-# gsane-scanner.h \
-# gsane-scanner.c \
-# gsane-module.c \
-# gsane-meta-param.h \
-# gsane-meta-param.c \
-# gsane-common.h \
-# gsane-common.c
-
-# libgsane_la_LDFLAGS = -avoid-version -module
-
-# libgsane_la_LIBADD = \
-# -L$(top_builddir)/lib -l SONAME@ \
-# -lsane
+libgsane_la_SOURCES = \
+ gsane-common.h \
+ gsane-common.c \
+ gsane-option-handler.h \
+ gsane-option-handler.c \
+ gsane-option-manager.h \
+ gsane-option-manager.c \
+ gsane-scanner.h \
+ gsane-scanner.c \
+ gsane-backend.h \
+ gsane-backend.c \
+ gsane-module.c \
+ $(NULL)
+
+# gsane-meta-param.h \
+# gsane-meta-param.c \
+#
+
+libgsane_la_LDFLAGS = -avoid-version -module
+
+libgsane_la_LIBADD = \
+ -L$(top_builddir)/lib -l SONAME@ \
+ -lsane
EXTRA_DIST = \
- $(wildcard gsane-*.c) \
- $(wildcard gsane-*.h) \
$(NULL)
-#
+
## File created by the gnome-build tools
Modified: trunk/modules/gsane-backend.c
==============================================================================
--- trunk/modules/gsane-backend.c (original)
+++ trunk/modules/gsane-backend.c Thu Dec 11 21:21:11 2008
@@ -25,39 +25,13 @@
#include "gsane-backend.h"
#include "gsane-scanner.h"
-void gsb_probe_scanners (GnomeScanBackend *backend);
-
static GnomeScanBackendClass* parent_class = NULL;
GS_DEFINE_MODULE_TYPE (GSaneBackend, gsane_backend, GNOME_SCAN_TYPE_BACKEND);
-static void
-gsane_backend_init (GSaneBackend *object)
-{
- /* TODO: Add initialization code here */
-}
-
-static void
-gsane_backend_finalize (GObject *object)
-{
- /* TODO: Add deinitalization code here */
-
- G_OBJECT_CLASS (parent_class)->finalize (object);
-}
-
-static void
-gsane_backend_class_init (GSaneBackendClass *klass)
-{
- GObjectClass* object_class = G_OBJECT_CLASS (klass);
- GnomeScanBackendClass *backend_class = GNOME_SCAN_BACKEND_CLASS (klass);
- parent_class = GNOME_SCAN_BACKEND_CLASS (g_type_class_peek_parent (klass));
-
- backend_class->probe_scanners = gsb_probe_scanners;
-
- object_class->finalize = gsane_backend_finalize;
-}
-void gsb_probe_scanners(GnomeScanBackend *backend)
+static void*
+gsane_backend_probe_scanners(GnomeScanBackend *backend)
{
const SANE_Device **devices;
SANE_Status status;
@@ -69,7 +43,7 @@
for (i = 0; devices[i]; i++) {
scanner = gsane_scanner_new(devices[i]);
if (scanner) {
- gnome_scan_backend_add_scanner(backend, scanner);
+ g_signal_emit_by_name(backend, "scanner-added", scanner);
g_object_unref (scanner);
}
else {
@@ -77,5 +51,28 @@
devices[i]->name);
}
}
+
+ g_signal_emit_by_name(backend, "probe-done");
+ return NULL;
}
+static void
+gsane_backend_init (GSaneBackend *object)
+{
+}
+
+static void
+gsane_backend_finalize (GObject *object)
+{
+ G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+static void
+gsane_backend_class_init (GSaneBackendClass *klass)
+{
+ GObjectClass* object_class = G_OBJECT_CLASS (klass);
+ GnomeScanBackendClass *backend_class = GNOME_SCAN_BACKEND_CLASS (klass);
+
+ object_class->finalize = gsane_backend_finalize;
+ backend_class->probe_scanners = gsane_backend_probe_scanners;
+}
Modified: trunk/modules/gsane-common.c
==============================================================================
--- trunk/modules/gsane-common.c (original)
+++ trunk/modules/gsane-common.c Thu Dec 11 21:21:11 2008
@@ -21,7 +21,6 @@
*/
#include "gsane-common.h"
-#include <gnome-scan-param-specs.h>
gboolean
gsane_str_matches_strv (const gchar *name, const gchar **names)
Modified: trunk/modules/gsane-common.h
==============================================================================
--- trunk/modules/gsane-common.h (original)
+++ trunk/modules/gsane-common.h Thu Dec 11 21:21:11 2008
@@ -23,15 +23,7 @@
#ifndef _GSANE_COMMON_H_
#define _GSANE_COMMON_H_
-#if HAVE_CONFIG_H
-#include <config.h>
-#endif
-
#include <glib.h>
-#include <glib/gi18n.h>
-
-#undef _
-#define _(string) dgettext(GETTEXT_PACKAGE, string)
G_BEGIN_DECLS
@@ -43,8 +35,6 @@
#define GSANE_META_PARAM_QUARK g_quark_from_string("meta-param")
-GQuark gsane_meta_param_quark () G_GNUC_CONST;
-
gboolean gsane_str_matches_strv (const gchar *name, const gchar **names);
G_END_DECLS
Modified: trunk/modules/gsane-module.c
==============================================================================
--- trunk/modules/gsane-module.c (original)
+++ trunk/modules/gsane-module.c Thu Dec 11 21:21:11 2008
@@ -19,12 +19,15 @@
* Boston, MA 02110-1301, USA
*/
-
+#include <gmodule.h>
#include <sane/sane.h>
#include <gnome-scan-module.h>
+#include "gsane-common.h"
+#include "gsane-option-manager.h"
#include "gsane-backend.h"
#include "gsane-scanner.h"
-#include "gsane-common.h"
+
+static GSaneOptionManager *gsane_option_manager;
G_MODULE_EXPORT void
gnome_scan_module_init (GnomeScanModule *module)
@@ -35,24 +38,29 @@
status = sane_init(&version, NULL);
bind_textdomain_codeset("sane-backends","UTF-8");
- gs_debug (G_STRLOC ": SANE version is %i.%i.%i",
- SANE_VERSION_MAJOR(version),
- SANE_VERSION_MINOR(version),
- SANE_VERSION_BUILD(version));
+ g_message (G_STRLOC ": SANE version is %i.%i.%i",
+ SANE_VERSION_MAJOR(version),
+ SANE_VERSION_MINOR(version),
+ SANE_VERSION_BUILD(version));
if (SANE_VERSION_MAJOR(version) != SANE_CURRENT_MAJOR) {
g_warning (G_STRLOC ": SANE major version must be %i.",
- SANE_CURRENT_MAJOR);
+ SANE_CURRENT_MAJOR);
return;
}
- gsane_scanner_register_type (G_TYPE_MODULE (module));
gsane_backend_register_type (G_TYPE_MODULE (module));
+ gsane_scanner_register_type (G_TYPE_MODULE (module));
+
+ /* GSane option handling */
+ gsane_option_manager = gsane_option_manager_new();
}
G_MODULE_EXPORT void
gnome_scan_module_finalize (GnomeScanModule *module)
{
+ /* TODO: backend and scanners */
+ gsane_option_manager_destroy(gsane_option_manager);
sane_exit();
}
Added: trunk/modules/gsane-option-handler.c
==============================================================================
--- (empty file)
+++ trunk/modules/gsane-option-handler.c Thu Dec 11 21:21:11 2008
@@ -0,0 +1,82 @@
+/* GSane - SANE GNOME Scan backend
+ * Copyright  2007-2008 Ãtienne Bersac <bersace gnome org>
+ *
+ * GSane is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * GSane is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with GSane. If not, write to:
+ *
+ * the Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301, USA
+ */
+
+#include "gsane-option-handler.h"
+
+#define GSANE_OPTION_HANDLER_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), GSANE_TYPE_OPTION_HANDLER, GSaneOptionHandlerPrivate))
+
+struct _GSaneOptionHandlerPrivate
+{
+ /* pointer to the SANE handle owned by the GSaneScanner */
+ gpointer* handle;
+};
+
+GSaneOptionHandler*
+gsane_option_handler_new(GType type, gpointer* handle)
+{
+ GSaneOptionHandler *self = GSANE_OPTION_HANDLER(g_type_create_instance(type));
+ self->priv->handle = handle;
+ return self;
+}
+
+/* GType instance boiler plate code */
+void
+gsane_option_handler_instance_init(GTypeInstance *instance, gpointer g_class)
+{
+ GSaneOptionHandler *self = GSANE_OPTION_HANDLER(instance);
+ self->priv = GSANE_OPTION_HANDLER_GET_PRIVATE(instance);
+}
+
+void
+gsane_option_handler_class_init(gpointer g_class, gpointer class_data)
+{
+ GSaneOptionHandlerClass *oh_class = GSANE_OPTION_HANDLER_CLASS(g_class);
+ g_type_class_add_private(g_class, sizeof(GSaneOptionHandlerPrivate));
+ oh_class->unique = FALSE;
+}
+
+GType
+gsane_option_handler_get_type()
+{
+ static GType type = 0;
+ static GTypeInfo tinfo = {
+ .class_size = sizeof(GSaneOptionHandlerClass),
+ .base_init = NULL,
+ .base_finalize = NULL,
+ .class_init = gsane_option_handler_class_init,
+ .class_finalize = NULL,
+ .class_data = NULL,
+ .instance_size = sizeof(GSaneOptionHandler),
+ .n_preallocs = 0,
+ .instance_init = gsane_option_handler_instance_init,
+ .value_table = NULL,
+ };
+ static GTypeFundamentalInfo finfo = {
+ .type_flags = G_TYPE_FLAG_CLASSED | G_TYPE_FLAG_INSTANTIATABLE | G_TYPE_FLAG_DERIVABLE,
+ };
+
+ if (G_UNLIKELY(type == 0)) {
+ type = g_type_fundamental_next();
+ g_type_register_fundamental(type, "GSaneOptionHandler", &tinfo, &finfo, G_TYPE_FLAG_ABSTRACT);
+ }
+
+ return type;
+}
Added: trunk/modules/gsane-option-handler.h
==============================================================================
--- (empty file)
+++ trunk/modules/gsane-option-handler.h Thu Dec 11 21:21:11 2008
@@ -0,0 +1,63 @@
+/* GSane - SANE GNOME Scan backend
+ * Copyright  2007-2008 Ãtienne Bersac <bersace gnome org>
+ *
+ * GSane is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * GSane is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with GSane. If not, write to:
+ *
+ * the Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301, USA
+ */
+
+#ifndef _GSANE_OPTION_HANDLER_H_
+#define _GSANE_OPTION_HANDLER_H_
+
+#include <glib-object.h>
+#include <sane/sane.h>
+
+G_BEGIN_DECLS
+
+#define GSANE_TYPE_OPTION_HANDLER (gsane_option_handler_get_type())
+#define GSANE_OPTION_HANDLER(o) (G_TYPE_CHECK_INSTANCE_CAST((o), GSANE_TYPE_OPTION_HANDLER, GSaneOptionHandler))
+#define GSANE_OPTION_HANDLER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GSANE_TYPE_OPTION_HANDLER, GSaneOptionHandlerClass))
+
+typedef struct _GSaneOptionHandlerClass GSaneOptionHandlerClass;
+typedef struct _GSaneOptionHandler GSaneOptionHandler;
+typedef struct _GSaneOptionHandlerPrivate GSaneOptionHandlerPrivate;
+
+struct _GSaneOptionHandlerClass
+{
+ GTypeClass parent_class;
+ /* Whether the scanner must have a unique instance of the
+ option handler */
+ gboolean unique;
+};
+
+struct _GSaneOptionHandler
+{
+ GTypeInstance parent_instance;
+ GSaneOptionHandlerPrivate* priv;
+};
+
+GType
+gsane_option_handler_get_type(void) G_GNUC_CONST;
+
+gint
+gsane_option_handler_get_int(GSaneOptionHandler handler, SANE_Int index);
+
+gboolean
+gsane_option_handler_set_int(GSaneOptionHandler handler, SANE_Int index, gint value);
+
+G_END_DECLS
+
+#endif
Added: trunk/modules/gsane-option-manager.c
==============================================================================
--- (empty file)
+++ trunk/modules/gsane-option-manager.c Thu Dec 11 21:21:11 2008
@@ -0,0 +1,111 @@
+/* GSane - SANE GNOME Scan backend
+ * Copyright  2007-2008 Ãtienne Bersac <bersace gnome org>
+ *
+ * GSane is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * GSane is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with GSane. If not, write to:
+ *
+ * the Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301, USA
+ */
+
+#include "gsane-option-manager.h"
+
+#define GSANE_OPTION_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), GSANE_TYPE_OPTION_MANAGER, GSaneOptionManagerPrivate))
+
+struct _GSaneOptionManagerPrivate
+{
+ GHashTable* name_rules;
+ GHashTable* type_rules;
+};
+
+/* singleton instance pointer */
+static GSaneOptionManager* gsane_option_manager = NULL;
+
+GSaneOptionManager*
+gsane_option_manager_new()
+{
+ if (G_UNLIKELY(gsane_option_manager == NULL)) {
+ gsane_option_manager = GSANE_OPTION_MANAGER(g_type_create_instance(GSANE_TYPE_OPTION_MANAGER));
+ }
+
+ return gsane_option_manager;
+}
+
+void
+gsane_option_manager_destroy(GSaneOptionManager *self)
+{
+ g_type_free_instance((GTypeInstance*)self);
+}
+
+void
+gsane_option_manager_add_rule_by_type(GSaneOptionManager* self, GType value_type, GType handler_type)
+{
+ g_hash_table_insert(self->priv->type_rules, (gpointer) value_type, (gpointer) handler_type);
+}
+
+void
+gsane_option_manager_add_rule_by_name(GSaneOptionManager* self, const gchar* name, GType handler_type)
+{
+ g_hash_table_insert(self->priv->type_rules, g_strdup(name), (gpointer)handler_type);
+}
+
+GType
+gsane_option_manager_get_handler_type(GSaneOptionManager* self, SANE_Int n)
+{
+ return G_TYPE_INVALID;
+}
+
+/* GLib type boiler plate code */
+void
+gsane_option_manager_class_init(gpointer g_class, gpointer class_data)
+{
+ g_type_class_add_private(g_class, sizeof(GSaneOptionManagerPrivate));
+}
+
+void
+gsane_option_manager_instance_init(GTypeInstance* instance, gpointer g_class)
+{
+ GSaneOptionManager *self = GSANE_OPTION_MANAGER(instance);
+ self->priv = GSANE_OPTION_MANAGER_GET_PRIVATE(instance);
+ self->priv->name_rules = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL);
+ self->priv->type_rules = g_hash_table_new(g_int_hash, g_int_equal);
+}
+
+GType
+gsane_option_manager_get_type()
+{
+ static GType type;
+ static const GTypeInfo tinfo = {
+ .class_size = sizeof(GSaneOptionManagerClass),
+ .base_init = NULL,
+ .base_finalize = NULL,
+ .class_init = gsane_option_manager_class_init,
+ .class_finalize = NULL,
+ .class_data = NULL,
+ .instance_size = sizeof(GSaneOptionManager),
+ .n_preallocs = 0,
+ .instance_init = gsane_option_manager_instance_init,
+ .value_table = NULL,
+ };
+ static const GTypeFundamentalInfo finfo = {
+ .type_flags = G_TYPE_FLAG_CLASSED | G_TYPE_FLAG_INSTANTIATABLE | G_TYPE_FLAG_DERIVABLE,
+ };
+
+ if (G_UNLIKELY(type == 0)) {
+ type = g_type_fundamental_next();
+ g_type_register_fundamental(type, "GSaneOptionManager", &tinfo, &finfo, 0);
+ }
+
+ return type;
+}
Added: trunk/modules/gsane-option-manager.h
==============================================================================
--- (empty file)
+++ trunk/modules/gsane-option-manager.h Thu Dec 11 21:21:11 2008
@@ -0,0 +1,58 @@
+/* GSane - SANE GNOME Scan backend
+ * Copyright  2007-2008 Ãtienne Bersac <bersace gnome org>
+ *
+ * GSane is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * GSane is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with GSane. If not, write to:
+ *
+ * the Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301, USA
+ */
+
+#ifndef _GSANE_OPTION_MANAGER_H_
+#define _GSANE_OPTION_MANAGER_H_
+
+#include <glib-object.h>
+#include <sane/sane.h>
+
+G_BEGIN_DECLS
+
+#define GSANE_TYPE_OPTION_MANAGER (gsane_option_manager_get_type())
+#define GSANE_OPTION_MANAGER(o) (G_TYPE_CHECK_INSTANCE_CAST((o), GSANE_TYPE_OPTION_MANAGER, GSaneOptionManager))
+#define GSANE_OPTION_MANAGER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GSANE_TYPE_OPTION_MANAGER, GSaneOptionManagerClass))
+
+typedef struct _GSaneOptionManagerClass GSaneOptionManagerClass;
+typedef struct _GSaneOptionManager GSaneOptionManager;
+typedef struct _GSaneOptionManagerPrivate GSaneOptionManagerPrivate;
+
+struct _GSaneOptionManagerClass
+{
+ GTypeClass parent_class;
+};
+
+struct _GSaneOptionManager
+{
+ GTypeInstance parent_instance;
+ GSaneOptionManagerPrivate* priv;
+};
+
+GSaneOptionManager* gsane_option_manager_new(void);
+void gsane_option_manager_destroy(GSaneOptionManager *self);
+void gsane_option_manager_add_rule_by_type(GSaneOptionManager* self, GType value_type, GType handler_type);
+void gsane_option_manager_add_rule_by_name(GSaneOptionManager* self, const gchar* name, GType handler_type);
+GType gsane_option_manager_get_handler_type(GSaneOptionManager* self, SANE_Int n);
+GType gsane_option_manager_get_type(void) G_GNUC_CONST;
+
+G_END_DECLS
+
+#endif
Modified: trunk/modules/gsane-scanner.c
==============================================================================
--- trunk/modules/gsane-scanner.c (original)
+++ trunk/modules/gsane-scanner.c Thu Dec 11 21:21:11 2008
@@ -1,1235 +1,180 @@
-/* Gnome Scan - Scan as easy as you print
- * Copyright  2007 Ãtienne Bersac <bersace gnome org>
+/* GSane - SANE GNOME Scan backend
+ * Copyright  2007-2008 Ãtienne Bersac <bersace gnome org>
*
- * Gnome Scan is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
+ * GSane is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
*
- * gnome-scan is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * GSane is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
- * License along with gnome-scan. If not, write to:
+ * License along with GSane. If not, write to:
*
* the Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301, USA
*/
-#include <glib/gi18n.h>
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <config.h>
+#include <glib/gi18n-lib.h>
#include <gegl.h>
#include <string.h>
#include <gnome-scan-module.h>
#include <gnome-scan-module-helper.h>
-#include <gnome-scan-param-specs.h>
+#include <sane/sane.h>
#include "gsane-common.h"
#include "gsane-scanner.h"
-#include "gsane-meta-param.h"
-#define GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GSANE_TYPE_SCANNER, GSaneScannerPrivate))
+#define GSANE_SCANNER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GSANE_TYPE_SCANNER, GSaneScannerPrivate))
-
-typedef struct _GSaneScannerPrivate GSaneScannerPrivate;
-typedef void (* GSSDataFunc) (GSaneScanner *sane,
- GeglRectangle *rect,
- Babl *format,
- guchar *buf,
- gint len);
struct _GSaneScannerPrivate
{
- /* INTERNALS */
- GThread* init_thread;
-
- /* SANE */
- gchar* sane_id;
- gchar* sane_type;
- SANE_Handle handle;
-
- /* Aquisition */
- SANE_Parameters params;
- SANE_Int data_len;
- SANE_Int chunk_len;
- guint bytes_read;
- gchar* format;
- GeglBuffer *buffer;
- GeglNode *load;
- guint n_frames;
- guint frame_no;
-
- /* NULL terminated list of MetaParams */
- GHashTable* meta_params;
-
- /* temp */
- gboolean reload;
- gboolean changed;
- gboolean first;
- GnomeScanSettings *settings;
-};
+ gchar* sane_id;
+ gchar* sane_type;
-enum
- {
- PROP_0,
- PROP_SANE_ID,
- PROP_SANE_TYPE
- };
-
-static GnomeScanScannerClass* parent_class = NULL;
-
-/* PLUGIN API */
-static void gss_configure (GnomeScanPlugin *plugin,
- GnomeScanSettings *settings);
-static GList* gss_get_child_nodes (GnomeScanPlugin *plugin,
- GeglNode *root);
-static gboolean gss_start_frame (GnomeScanPlugin *plugin);
-static gboolean gss_work (GnomeScanPlugin *plugin,
- gdouble *progress);
-static void gss_end_frame (GnomeScanPlugin *plugin);
-
-/* SCANNER API */
-gchar* gss_get_output_format (GnomeScanScanner *scanner);
-
-
-/* INTERNALS */
-static void gss_init (GSaneScanner *sane);
-
-/* OPTIONS */
-static void gss_probe_options (GSaneScanner *sane);
-static void gss_mp_foreach_option_matches (const gchar *key,
- MetaParam *mp,
- GPtrArray* arg);
-static void gss_mp_foreach_add_param (const gchar* key,
- MetaParam *mp,
- GSaneScanner *sane);
-
-static void gss_params_foreach_set_param (GParamSpec *spec,
- GSaneScanner *gss);
-static GParamSpec* gss_option_get_param_spec (GSaneScanner *sane,
- SANE_Int n);
-static void gss_params_foreach_update_param (GParamSpec *pspec,
- GSaneScanner *gss);
-static void gss_option_set_default_value_by_index (GSaneScanner *gss,
- SANE_Int n,
- GType type);
-static GValue* gss_option_get_value_by_index (GSaneScanner *sane,
- SANE_Int n,
- GType type);
+ gboolean probe_done;
+ SANE_Handle handle;
+};
-/* utils */
-#define gss_option_name_matches_array(spec,names) gsane_str_matches_strv(g_param_spec_get_name(spec),names)
+enum {
+ GSANE_SCANNER_DUMMY_PROPERTY,
+ GSANE_SCANNER_SANE_ID,
+ GSANE_SCANNER_SANE_TYPE,
+};
GS_DEFINE_MODULE_TYPE (GSaneScanner, gsane_scanner, GNOME_SCAN_TYPE_SCANNER);
-#define GSANE_OPTION_DESC_QUARK (gsane_option_desc_quark ())
-GS_DEFINE_QUARK(gsane_option_desc, "sane-option-desc");
-
-
-static GObject*
-gsane_scanner_constructor(GType type, guint n, GObjectConstructParam *params)
-{
- GObject *object =
- G_OBJECT_CLASS(parent_class)->constructor(type, n, params);
- GError *error = NULL;
-
- GSaneScannerPrivate *priv = GET_PRIVATE(object);
- SANE_Status status;
-
- /* v4l set type as "virtual device". Welcome to the bazar of
- SANE backends :( */
- if (g_str_equal(priv->sane_type, "video camera")
- || g_str_equal(priv->sane_type, "webcam")
- || g_strstr_len(priv->sane_id, 4, "v4l")) {
- g_debug("Ignoring %s %s", priv->sane_type, priv->sane_id);
- return NULL;
- }
-
- status = sane_open (priv->sane_id, &(priv->handle));
-
- if (status != SANE_STATUS_GOOD) {
- g_warning ("Unable to open device %s (%s) : %s",
- gnome_scan_plugin_get_name (GNOME_SCAN_PLUGIN (object)),
- priv->sane_id, sane_strstatus (status));
- return NULL;
- }
-
-
-
- /* Since the use needs to select the scanner before showing
- options, we can do the probe in a seperate thread, this
- will quicken the probe, while the user choose the
- device. */
- priv->init_thread = g_thread_create((GThreadFunc) gss_init,
- GSANE_SCANNER(object),
- TRUE, &error);
-
- return object;
-}
-
-static void
-gsane_scanner_init (GSaneScanner *object)
-{
- GSaneScannerPrivate *priv = GET_PRIVATE (object);
- priv->meta_params = g_hash_table_new (g_str_hash,
- g_str_equal);
-}
-
-static void
-gsane_scanner_finalize (GObject *object)
-{
- GSaneScannerPrivate *priv = GET_PRIVATE (object);
-
- if (priv->init_thread) {
- g_thread_join (priv->init_thread);
- }
-
- g_hash_table_destroy (priv->meta_params);
- sane_close(priv->handle);
- g_free(priv->sane_type);
- g_free(priv->sane_id);
-
- G_OBJECT_CLASS (parent_class)->finalize (object);
-}
-
-static void
-gsane_scanner_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
-{
- g_return_if_fail (GNOME_IS_SCANNER_SANE (object));
-
- switch (prop_id)
- {
- case PROP_SANE_ID:
- GET_PRIVATE (object)->sane_id = g_value_dup_string(value);
- break;
- case PROP_SANE_TYPE:
- GET_PRIVATE (object)->sane_type = g_value_dup_string(value);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-#if 0
-static void
-gsane_scanner_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
-{
- g_return_if_fail (GNOME_IS_SCANNER_SANE (object));
-
- switch (prop_id)
- {
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-#endif
-
-static void
-gsane_scanner_class_init (GSaneScannerClass *klass)
-{
- GObjectClass* object_class = G_OBJECT_CLASS (klass);
- parent_class = GNOME_SCAN_SCANNER_CLASS (g_type_class_peek_parent (klass));
- GnomeScanPluginClass* plugin_class = GNOME_SCAN_PLUGIN_CLASS (klass);
- GnomeScanScannerClass* scanner_class = GNOME_SCAN_SCANNER_CLASS (klass);
-
- g_type_class_add_private(object_class, sizeof(GSaneScannerPrivate));
-
- object_class->constructor = gsane_scanner_constructor;
- object_class->set_property = gsane_scanner_set_property;
-
- plugin_class->configure = gss_configure;
- plugin_class->get_child_nodes = gss_get_child_nodes;
- plugin_class->start_frame = gss_start_frame;
- plugin_class->work = gss_work;
- plugin_class->end_frame = gss_end_frame;
-
- scanner_class->get_output_format = gss_get_output_format;
- object_class->finalize = gsane_scanner_finalize;
-
- g_object_class_install_property (object_class,
- PROP_SANE_ID,
- g_param_spec_string ("sane-id",
- "SANE id",
- "SANE device identifier",
- "",
- G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
-
- g_object_class_install_property (object_class,
- PROP_SANE_TYPE,
- g_param_spec_string ("sane-type",
- "SANE device type",
- "SANE device type",
- "",
- G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
-}
-
-
GnomeScanScanner*
-gsane_scanner_new (const SANE_Device *device)
-{
- GObject *object =
- g_object_new (GSANE_TYPE_SCANNER,
- "name", g_strconcat(device->vendor,
- " ",
- device->model,
- NULL),
- "blurb", "",
- "icon-name", "scanner",
- "sane-id", device->name,
- "sane-type", device->type,
- NULL);
- return GNOME_SCAN_SCANNER (object);
-}
-
-/* PLUGIN API */
-
-static void
-gss_configure (GnomeScanPlugin *plugin,
- GnomeScanSettings *settings)
+gsane_scanner_new(const SANE_Device *device)
{
- GSaneScannerPrivate *priv = GET_PRIVATE (plugin);
-
- priv->settings = settings;
- priv->first = TRUE;
-
- gnome_scan_plugin_params_foreach (plugin,
- (GFunc) gss_params_foreach_set_param,
- GSANE_SCANNER (plugin));
-
- if (priv->reload) {
- gnome_scan_plugin_params_foreach (plugin,
- (GFunc) gss_params_foreach_update_param,
- GSANE_SCANNER (plugin));
- priv->reload = FALSE;
- }
- priv->settings = NULL;
-}
+ gchar* name = g_strconcat(device->vendor, " ", device->model, NULL);
+ GObject* object= g_object_new(GSANE_TYPE_SCANNER,
+ "name", name,
+ "icon-name", "scanner",
+ "sane-id", device->name,
+ "sane-type", device->type,
+ NULL);
+ g_free(name);
-static GList*
-gss_get_child_nodes (GnomeScanPlugin *plugin,
- GeglNode *root)
-{
- GSaneScannerPrivate *priv = GET_PRIVATE (plugin);
- GList* list = NULL;
-
- priv->load = gegl_node_new_child (root,
- "operation", "gegl:load-buffer",
- "buffer", priv->buffer,
- NULL);
- list = g_list_append (list, priv->load);
- return list;
+ return GNOME_SCAN_SCANNER(object);
}
-static gboolean
-gss_sane_start (GSaneScanner *gss)
+gboolean
+gsane_scanner_sane_status_is_good(GSaneScanner *self, const gchar* operation, SANE_Status status)
{
- GSaneScannerPrivate *priv = GET_PRIVATE (gss);
- SANE_Status status;
-
- status = sane_start (priv->handle);
- if (status != SANE_STATUS_GOOD) {
- g_debug (G_STRLOC ": %s", sane_strstatus (status));
- return FALSE;
- }
-
- status = sane_get_parameters (priv->handle, &priv->params);
+ /* TODO: update node status, handle error/warning */
if (status != SANE_STATUS_GOOD) {
- g_debug (G_STRLOC ": %s", sane_strstatus (status));
- return FALSE;
+ const SANE_String_Const message = sane_strstatus(status);
+ g_warning("SANE operation : %s failed with %s", operation, message);
+ gnome_scan_node_update_status(GNOME_SCAN_NODE(self), GNOME_SCAN_STATUS_FAILED, message);
}
-
- priv->bytes_read = 0;
- priv->frame_no++;
-
- return TRUE;
+ return status == SANE_STATUS_GOOD;
}
-static gboolean
-gss_start_frame (GnomeScanPlugin *plugin)
+/* GThreadFunc */
+static void*
+gsane_scanner_probe_options(GSaneScanner *self)
{
- GSaneScanner *gss = GSANE_SCANNER (plugin);
- GSaneScannerPrivate *priv = GET_PRIVATE (gss);
- gboolean first = priv->first;
- Babl *format;
- gchar *fmt;
-
- priv->bytes_read = 0;
- priv->frame_no = 0;
-
- if (first || gss->adf) {
- if (!gss_sane_start (gss))
- return FALSE;
-
- priv->format = fmt = g_strdup_printf("%s u%i",
- priv->params.format == SANE_FRAME_GRAY ? "Y" : "RGB",
- MAX(8, priv->params.depth));
- format = babl_format(fmt);
-
- priv->chunk_len = priv->params.bytes_per_line;
- priv->data_len = priv->params.bytes_per_line * priv->params.lines;
- priv->n_frames = 3;
-
- GeglRectangle extent = {0, 0, priv->params.pixels_per_line, priv->params.lines};
- priv->buffer = gegl_buffer_new (&extent, format);
-
- g_debug (G_STRLOC ": buffer is %p in format %s",
- priv->buffer, fmt);
-
- gegl_node_set (priv->load,
- "buffer", priv->buffer,
- NULL);
-
- priv->first = FALSE;
- return TRUE;
- }
-
- return FALSE;
-}
-
-gchar*
-gss_get_output_format (GnomeScanScanner *scanner)
-{
- return GET_PRIVATE (scanner)->format;
-}
+ SANE_Status status;
+ SANE_Int count;
+ status = sane_open(self->priv->sane_id, &self->priv->handle);
+ gchar *operation = g_strdup_printf("sane_open(%s)", self->priv->sane_id);
+ if (!gsane_scanner_sane_status_is_good(self, operation, status))
+ goto end;
+ g_free(operation);
-/* ACQUISITION */
+ sane_control_option(self->priv->handle, 0, SANE_ACTION_GET_VALUE, &count,NULL);
+ g_debug("Devices %s : %i options", self->priv->sane_id, count);
+ gnome_scan_node_update_status(GNOME_SCAN_NODE(self), GNOME_SCAN_STATUS_UNCONFIGURED, NULL);
-#if DEBUG
-/* return a string of [01] corresponding to @bt */
-gchar*
-byte_to_string (guchar bt)
-{
- guint i;
- gchar *s = g_new0(gchar, 9);
- for (i = 0; i < 8; i++) {
- sprintf(s, "%s%i", s, (bt & (1<<(7-i))) ? 1 : 0);
- }
- return s;
+ end:
+ self->priv->probe_done = TRUE;
+ return NULL;
}
-#endif
-
-/* process 1bit RGB data into RGB 8 */
-static void
-gss_data_color1 (GSaneScanner *gss, GeglRectangle *rect, Babl* format, guchar *buf, gint len)
+static GObject*
+gsane_scanner_constructor(GType type, guint n_construct_properties, GObjectConstructParam* construct_params)
{
- guint i, tlen;
- guchar *tbuf, mask, val;
-
- tlen = len * 8;
- tbuf = g_new0 (guchar, tlen);
- /* we loop each bit */
- for (i = 0; i < tlen; i++) {
- /* get the byte containing the inth bit */
- val = buf[i/8];
- /* first bit is the MSB */
- mask = (0x80 >> (i%8));
- tbuf[i] = (val & mask) ? 0xFF : 0x00;
- }
- gegl_buffer_set (GET_PRIVATE (gss)->buffer,
- rect,
- format,
- tbuf,
- GEGL_AUTO_ROWSTRIDE);
- g_free (tbuf);
-}
-
+ GObject* object = G_OBJECT_CLASS(gsane_scanner_parent_class)->constructor(type, n_construct_properties, construct_params);
+ GSaneScanner *self = GSANE_SCANNER(object);
+ GError *error = NULL;
-/* process 8/16 bit RGB in to â 8/16 bit RGB */
-static void
-gss_data_color (GSaneScanner *gss,
- GeglRectangle *rect,
- Babl* format,
- guchar* buf,
- gint len)
-{
- gegl_buffer_set (GET_PRIVATE (gss)->buffer,
- rect,
- format,
- buf,
- GEGL_AUTO_ROWSTRIDE);
-}
+ g_thread_create((GThreadFunc) gsane_scanner_probe_options, self, FALSE, &error);
-/* process 1 bit RGB into RGB 8bit */
-static void
-gss_data_color1_three_pass (GSaneScanner *gss,
- GeglRectangle *rect,
- Babl* format,
- guchar *buf,
- gint len)
-{
- GSaneScannerPrivate *priv = GET_PRIVATE (gss);
- guchar *tbuf;
- guint i, offset = 0, tlen = len * 8;
- guchar mask;
-
- switch (priv->params.format) {
- case SANE_FRAME_RED:
- offset = 0;
- break;
- case SANE_FRAME_GREEN:
- offset = 1;;
- break;
- case SANE_FRAME_BLUE:
- offset = 2;;
- break;
- default:
- break;
- }
-
- tbuf = g_new0 (guchar, tlen * 3);
- gegl_buffer_get (priv->buffer, 1., rect, format, tbuf, GEGL_AUTO_ROWSTRIDE);
- for (i = 0; i < tlen; i++) {
- mask = 0x80 >> (i%8);
- tbuf[i*3+offset] = (buf[i/8] & mask) ? 0xFF : 0x00;
- }
- gegl_buffer_set (priv->buffer, rect, format, tbuf,
- GEGL_AUTO_ROWSTRIDE);
- g_free (tbuf);
-}
-
-/* 8/16 bit three pass RGB */
-static void
-gss_data_color_three_pass (GSaneScanner *gss,
- GeglRectangle *rect,
- Babl* format,
- guchar* buf,
- gint len)
-{
- GSaneScannerPrivate *priv = GET_PRIVATE (gss);
- guchar *tbuf;
- guint i, offset = 0, px_stride, sp_stride;
-
-
- /* sample stride */
- sp_stride = priv->params.depth/8;
- px_stride = 3 * sp_stride;
-
- switch (priv->params.format) {
- case SANE_FRAME_RED:
- offset = 0;
- break;
- case SANE_FRAME_GREEN:
- offset = 1;
- break;
- case SANE_FRAME_BLUE:
- offset = 2;
- break;
- default:
- break;
- }
- offset*= sp_stride;
-
- tbuf = g_new0 (guchar, len*3);
- gegl_buffer_get (priv->buffer, 1., rect, NULL, tbuf, GEGL_AUTO_ROWSTRIDE);
-
- for (i = 0; i < len/sp_stride; i++) {
- /* copy 1 or 2 bytes of sample at the right place */
- memcpy(tbuf+i*px_stride+offset, buf+i*sp_stride, sp_stride);
+ if (error) {
+ g_warning("Unable to init thread : %s",
+ dgettext(g_quark_to_string(error->domain), error->message));
+ return NULL;
}
-
- gegl_buffer_set (priv->buffer, rect, NULL, tbuf,
- GEGL_AUTO_ROWSTRIDE);
- g_free (tbuf);
-}
-/* Black&White */
-static void
-gss_data_gray1 (GSaneScanner *gss, GeglRectangle *rect, Babl* format, guchar* buf, gint len)
-{
- guchar *tbuf;
- guint i, tlen;
- guchar mask;
-
- tlen = 8 * len;
- tbuf = g_new0 (guchar, tlen);
- for (i = 0; i < tlen; i++) {
- mask = 0x80 >> (i%8);
- tbuf[i] = (buf[i/8] & mask) ? 0xFF : 0x00;
- }
- gegl_buffer_set (GET_PRIVATE (gss)->buffer, rect, format, tbuf,
- GEGL_AUTO_ROWSTRIDE);
- g_free (tbuf);
+ return object;
}
-/* 8/16 bit gray */
static void
-gss_data_gray (GSaneScanner *gss, GeglRectangle *rect, Babl* format, guchar* buf, gint len)
-{
- gegl_buffer_set (GET_PRIVATE (gss)->buffer, rect, format, buf,
- GEGL_AUTO_ROWSTRIDE);
-}
-
-
-static gboolean
-gss_work (GnomeScanPlugin *plugin, gdouble *progress)
+gsane_scanner_init(GSaneScanner *self)
{
- GSaneScanner *gss = GSANE_SCANNER (plugin);
- GSaneScannerPrivate *priv = GET_PRIVATE (gss);
- GeglRectangle rect;
- SANE_Status status;
- Babl* format;
- SANE_Byte *buf;
- SANE_Int len;
- GSSDataFunc processor = NULL;
-
- buf = g_new0 (SANE_Byte, priv->chunk_len);
- status = sane_read (priv->handle, buf, priv->chunk_len, &len);
-
- /* start new frame for three pass acquisition */
- if (status == SANE_STATUS_EOF && !priv->params.last_frame) {
- g_free (buf);
- return gss_sane_start (gss);
- }
-
- /* EOF, NO_DOCS, errors â */
- if (status != SANE_STATUS_GOOD) {
- gs_debug (G_STRLOC ": %s", sane_strstatus (status));
- g_free (buf);
- return FALSE;
- }
-
- /* determine which function to call */
- switch (priv->params.format) {
- case SANE_FRAME_RGB:
- processor = priv->params.depth == 1 ? gss_data_color1 : gss_data_color;
- priv->n_frames = 1;
- break;
- case SANE_FRAME_RED:
- case SANE_FRAME_GREEN:
- case SANE_FRAME_BLUE:
- processor = (priv->params.depth == 1) ? gss_data_color1_three_pass : gss_data_color_three_pass;
- break;
- case SANE_FRAME_GRAY:
- processor = (priv->params.depth == 1) ? gss_data_gray1 : gss_data_gray;
- break;
- default:
- g_warning ("Frame format not supported");
- return FALSE;
- break;
- }
-
- rect.x = priv->bytes_read % priv->params.bytes_per_line;
- rect.y = priv->bytes_read / priv->params.bytes_per_line;
- rect.height = len / priv->params.bytes_per_line;
- rect.width = priv->params.pixels_per_line;
-
- g_object_get (priv->buffer, "format", &format, NULL);
-
- if (processor)
- processor(gss, &rect, format, buf, len);
-
- g_free (buf);
- priv->bytes_read+= len;
-
- /* This very complex formula compute the right progress over one or three frame */
- *progress = ((gdouble) priv->frame_no-1) * (1./(gdouble) priv->n_frames) + ((gdouble) priv->bytes_read / (gdouble) priv->data_len) / (gdouble) priv->n_frames;
- return TRUE;
+ self->priv = GSANE_SCANNER_GET_PRIVATE(self);
+ self->priv->probe_done = FALSE;
}
static void
-gss_end_frame (GnomeScanPlugin *plugin)
+gsane_scanner_finalize(GObject *object)
{
- GSaneScanner *gss = GSANE_SCANNER (plugin);
- GSaneScannerPrivate *priv = GET_PRIVATE (gss);
- sane_cancel (priv->handle);
- g_object_unref (priv->buffer);
- g_free (priv->format);
- priv->format = NULL;
- priv->buffer = NULL;
+ GSaneScanner *self = GSANE_SCANNER(object);
+ self->priv->sane_id = (self->priv->sane_id == NULL ? NULL : g_free(self->priv->sane_id), NULL);
+ self->priv->sane_type = (self->priv->sane_type == NULL ? NULL : g_free(self->priv->sane_type), NULL);
}
-
-
-
-
-/* INTERNALS */
-
static void
-gss_init (GSaneScanner *gss)
+gsane_scanner_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec)
{
- GSaneScannerPrivate *priv = GET_PRIVATE (gss);
- MetaParam *mp;
-
- /* declare MetaParams */
-#define gss_mp_new(name, gss) mp = meta_param_##name(gss); \
- g_hash_table_insert (priv->meta_params, meta_param_get_name (mp), mp)
-
- gss_mp_new(paper_size, gss);
- gss_mp_new(source, gss);
- gss_mp_new(preview, gss);
-
-#undef gss_mp_new
-
- /* launch options probe */
- gss_probe_options (gss);
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
}
static void
-gss_probe_options(GSaneScanner *gss)
+gsane_scanner_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec)
{
- GSaneScannerPrivate *priv = GET_PRIVATE (gss);
- GParamSpec *spec;
- GPtrArray *arg = g_ptr_array_sized_new (3);
- GValue *value;
- MetaParam *mp = NULL;
- gint n, i;
- static const gchar*front_option_names[] = {
- "resolution",
- "source",
- "mode",
- NULL
- };
- static const gchar*hidden_options[] = {
- NULL
- };
-
- gnome_scan_scanner_set_status (GNOME_SCAN_SCANNER (gss),
- GNOME_SCAN_STATUS_BUSY);
-
- spec = gss_option_get_param_spec (gss, 0);
- value = gsane_scanner_option_get_value(gss, spec);
- n = g_value_get_int(value);
- g_free(value);
-
- gs_debug(" === Device %s (%d options) ===",
- gnome_scan_plugin_get_name(GNOME_SCAN_PLUGIN(gss)), n);
-
- g_ptr_array_add (arg, gss);
- g_ptr_array_add (arg, &mp);
-
- /* loop each sane option */
- for (i = 1; i < n; i++) {
- /* get corresponding spec */
- spec = gss_option_get_param_spec(gss, i);
- if (spec) {
- /* override group for front options */
- if (gss_option_name_matches_array (spec, front_option_names)) {
- gs_param_spec_set_group (spec, GS_PARAM_GROUP_SCANNER_FRONT);
- }
-
- if (gss_option_name_matches_array (spec, hidden_options)) {
- gs_param_spec_set_group (spec, GS_PARAM_GROUP_HIDDEN);
- }
-
-
- /* search if this option does not belong to a MetaParam */
- mp = NULL;
- g_ptr_array_add (arg, spec);
- g_hash_table_foreach (priv->meta_params,
- (GHFunc) gss_mp_foreach_option_matches,
- arg);
- g_ptr_array_remove (arg, spec);
-
- if (mp)
- meta_param_add_params (mp, spec);
- /* or add directly to scanner */
- else
- gnome_scan_plugin_params_add (GNOME_SCAN_PLUGIN (gss), spec);
- }
- }
-
- /* now ask each MetaParam to add its param to the scanner */
- g_hash_table_foreach (priv->meta_params,
- (GHFunc) gss_mp_foreach_add_param,
- gss);
- gs_debug ("\n");
-
-
-
- gnome_scan_scanner_set_status (GNOME_SCAN_SCANNER (gss), GNOME_SCAN_STATUS_READY);
- if (priv->changed) {
- gnome_scan_scanner_settings_changed (GNOME_SCAN_SCANNER (gss));
- priv->changed = FALSE;
- }
-
- g_thread_exit (NULL);
-}
-
-
-static GParamSpec*
-gss_option_get_param_spec (GSaneScanner *gss, SANE_Int n)
-{
- static GQuark group;
- static gint unnamed = 0;
-
- GSaneScannerPrivate *priv = GET_PRIVATE(gss);
- GParamSpec *spec = NULL;
- GValue *default_value = NULL, *value, *vmin, *vmax, *vstep;
- GValueArray *values;
- GType type = G_TYPE_INVALID;
- GType spec_type = G_TYPE_INVALID;
- gchar *constraint, *name, *sflags;
- gint i, m;
- guint flags = 0, unit;
- GEnumClass *enumclass;
- GEnumValue *enumvalue;
- const SANE_Option_Descriptor *desc;
-
- desc = sane_get_option_descriptor(priv->handle, n);
-
- /* FLAG */
- sflags = "";
- if (SANE_OPTION_IS_ACTIVE (desc->cap)) {
- flags = flags | G_PARAM_WRITABLE;
- sflags = "writable";
- }
-
- /* UNIT */
- switch (desc->unit) {
- case SANE_UNIT_PIXEL:
- unit = GNOME_SCAN_UNIT_PIXEL;
- break;
- case SANE_UNIT_BIT:
- unit = GNOME_SCAN_UNIT_BIT;
- break;
- case SANE_UNIT_MM:
- unit = GNOME_SCAN_UNIT_MM;
+ GSaneScanner *self;
+ self = GSANE_SCANNER(object);
+ switch(property_id) {
+ case GSANE_SCANNER_SANE_ID:
+ self->priv->sane_id = g_value_dup_string(value);
break;
- case SANE_UNIT_DPI:
- unit = GNOME_SCAN_UNIT_DPI;
+ case GSANE_SCANNER_SANE_TYPE:
+ self->priv->sane_type = g_value_dup_string(value);
break;
- case SANE_UNIT_PERCENT:
- unit = GNOME_SCAN_UNIT_PERCENT;
- break;
- case SANE_UNIT_MICROSECOND:
- unit = GNOME_SCAN_UNIT_PERCENT;
- break;
- case SANE_UNIT_NONE:
default:
- unit = GNOME_SCAN_UNIT_NONE;
- break;
- }
-
- enumclass = g_type_class_ref (GNOME_SCAN_TYPE_UNIT);
- enumvalue = g_enum_get_value (enumclass, unit);
- g_type_class_unref (enumclass);
-
- /* VALUE TYPE*/
- switch (desc->type) {
- case SANE_TYPE_BOOL:
- type = G_TYPE_BOOLEAN;
- break;
- case SANE_TYPE_INT:
- type = G_TYPE_INT;
- break;
- case SANE_TYPE_FIXED:
- type = G_TYPE_DOUBLE;
- break;
- case SANE_TYPE_STRING:
- type = G_TYPE_STRING;
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
break;
- case SANE_TYPE_GROUP:
- group = g_quark_from_string(desc->title);
- gs_debug ("\n");
- gs_debug (" -- Group ÂÂ%sÂÂ --", desc->title);
- type = G_TYPE_NONE;
- return NULL;
- break;
- case SANE_TYPE_BUTTON:
- gs_debug("// button : %s (%s)", desc->title, desc->desc);
- type = G_TYPE_NONE;
- return NULL;
- break;
- }
-
- /* workaround buggy epson driver */
- if (n == 0)
- type = G_TYPE_INT;
-
- name = g_utf8_strlen(desc->name, 32) < 1 ?
- g_strdup_printf("option-%i", unnamed++)
- : g_strdup (desc->name);
-
- if (desc->cap & SANE_CAP_HARD_SELECT) {
- gs_debug ("/!\\ IGNORING BUTTON %s !", name);
- return NULL;
- }
-
-
- /* SPEC_TYPE */
- switch (desc->constraint_type) {
- /* RANGE */
- case SANE_CONSTRAINT_RANGE:
- spec_type = GS_TYPE_PARAM_RANGE;
- break;
-
- /* ENUM */
- case SANE_CONSTRAINT_WORD_LIST:
- case SANE_CONSTRAINT_STRING_LIST:
- spec_type = GS_TYPE_PARAM_ENUM;
- break;
- case SANE_CONSTRAINT_NONE:
- constraint = NULL;
- switch (type) {
- case G_TYPE_BOOLEAN:
- spec_type = G_TYPE_PARAM_BOOLEAN;
- break;
- case G_TYPE_INT:
- spec_type = G_TYPE_PARAM_INT;
- break;
- case G_TYPE_DOUBLE:
- spec_type = G_TYPE_PARAM_DOUBLE;
- break;
- case G_TYPE_STRING:
- spec_type = G_TYPE_PARAM_STRING;
- break;
- default:
- spec_type = G_TYPE_NONE;
- break;
- }
- break;
- }
-
- if (type != G_TYPE_NONE) {
- if (desc->cap & SANE_CAP_AUTOMATIC)
- gss_option_set_default_value_by_index (gss, n, type);
- default_value = gss_option_get_value_by_index (gss, n, type);
- }
-
- /* SPEC */
- if (spec_type == G_TYPE_PARAM_BOOLEAN) {
- spec = gs_param_spec_boolean (name, desc->title, desc->desc, group,
- g_value_get_boolean (default_value), flags);
- }
- else if (spec_type == G_TYPE_PARAM_INT) {
- spec = gs_param_spec_int(name, desc->title, desc->desc, group,
- G_MININT, G_MAXINT,
- g_value_get_int (default_value), flags);
- }
- else if (spec_type == G_TYPE_PARAM_DOUBLE) {
- spec = gs_param_spec_double (name, desc->title, desc->desc, group,
- G_MINDOUBLE, G_MAXDOUBLE,
- MIN (G_MAXDOUBLE, MAX (G_MINDOUBLE, g_value_get_double (default_value))),
- flags);
- }
- else if (spec_type == G_TYPE_PARAM_STRING) {
- spec = gs_param_spec_string (name, desc->title, desc->desc, group,
- dgettext ("sane-backends",
- g_value_get_string (default_value)),
- flags);
- }
- else if (spec_type == GS_TYPE_PARAM_RANGE) {
- /* init values */
- value = g_new0(GValue, 1);
- g_value_init (value, type);
- vmin = g_new0(GValue, 1);
- g_value_init (vmin, type);
- vmax = g_new0(GValue, 1);
- g_value_init (vmax, type);
- vstep = g_new0(GValue, 1);
- g_value_init (vstep, type);
-
- /* set values */
- switch (type) {
- case G_TYPE_INT:
- g_value_set_int (vmin, desc->constraint.range->min);
- g_value_set_int (vmax, desc->constraint.range->max);
- g_value_set_int (vstep, desc->constraint.range->quant);
- break;
- case G_TYPE_DOUBLE:
- g_value_set_double (vmin, SANE_UNFIX (desc->constraint.range->min));
- g_value_set_double (vmax, SANE_UNFIX (desc->constraint.range->max));
- g_value_set_double (vstep, SANE_UNFIX (desc->constraint.range->quant));
- break;
- }
-
- constraint = g_strdup_printf ("[%s;%s;%s]",
- g_strdup_value_contents (vmin),
- g_strdup_value_contents (vstep),
- g_strdup_value_contents (vmax));
-
- /* create spec */
- spec = gs_param_spec_range(name, desc->title, desc->desc, group,
- vmin, vmax, vstep, default_value, flags);
-
- g_free (vmin);
- g_free (vmax);
- g_free (vstep);
- }
- /* ENUM */
- else if (spec_type == GS_TYPE_PARAM_ENUM) {
- value = g_new0(GValue, 1);
- g_value_init (value, type);
- constraint = "";
-
- if (type == G_TYPE_STRING) {
- values = g_value_array_new (0);
- for (i = 0; desc->constraint.string_list[i]; i++) {
- g_value_set_static_string (value,
- desc->constraint.string_list[i]);
- g_value_array_append(values, value);
- }
- if (g_value_get_string (default_value) == NULL) {
- g_value_unset (default_value);
- g_free (default_value);
- default_value = values->values;
- }
- constraint = g_strdup_printf ("{\"%s\"}",
- g_strjoinv("\", \"",
- (gchar**) desc->constraint.string_list));
- }
- else {
- m = (gint) desc->constraint.word_list[0];
- values = g_value_array_new (m);
- for (i = 0; i < m; i++) {
- switch (type) {
- case G_TYPE_INT:
- g_value_set_int (value, desc->constraint.word_list[i+1]);
- constraint = g_strdup_printf("%s, %d", constraint,
- g_value_get_int (value));
- break;
- case G_TYPE_DOUBLE:
- g_value_set_double (value, SANE_UNFIX(desc->constraint.word_list[i+1]));
- constraint = g_strdup_printf("%s; %.2f", constraint,
- g_value_get_double (value));
- break;
- }
- g_value_array_append (values, value);
- }
- constraint = g_strdup_printf("{%s}", constraint+2);
- }
- g_value_unset (value);
- g_free (value);
-
- spec = gs_param_spec_enum(name, desc->title, desc->desc, group,
- values, default_value, flags);
- }
- else if (spec_type == G_TYPE_NONE) {
- return NULL;
- }
-
- /* common specs datas */
- if (spec) {
- g_param_spec_set_qdata (spec, GSANE_OPTION_DESC_QUARK, (gpointer) desc);
- gs_param_spec_set_group (spec, group);
- gs_param_spec_set_domain (spec, "sane-backends");
- gs_param_spec_set_unit (spec, unit);
- gs_param_spec_set_index(spec, (guint) n);
}
-
- gs_debug ("%s (%s):", desc->title, desc->name);
- gs_debug (" %s %s (%s), %s",
- g_type_name(type), enumvalue->value_nick,
- g_type_name(spec_type), constraint);
- gs_debug (" default = %s ; flags = {%s}",
- g_strdup_value_contents (default_value), sflags);
- gs_debug ("%s", "");
-
- g_free (name);
- g_free (constraint);
-
- return spec;
}
-
static void
-gss_option_set_default_value_by_index (GSaneScanner *gss, SANE_Int n, GType type)
+gsane_scanner_class_init(GSaneScannerClass *klass)
{
- GSaneScannerPrivate *priv = GET_PRIVATE (gss);
- SANE_Status status;
- SANE_Int i;
-
- status = sane_control_option (priv->handle, n, SANE_ACTION_SET_AUTO,
- NULL, &i);
-}
+ GObjectClass *o_class = G_OBJECT_CLASS(klass);
+ /* GnomeScanNodeClass *n_class = GNOME_SCAN_NODE_CLASS(klass); */
-GValue*
-gsane_scanner_option_get_value (GSaneScanner *sane, GParamSpec *spec)
-{
- /* determine true value type using gs_param_value_set_default */
- GValue *default_value = g_new0 (GValue, 1);
- GType type;
- g_value_init (default_value, G_PARAM_SPEC_VALUE_TYPE (spec));
- g_param_value_set_default (spec, default_value);
- type = G_VALUE_TYPE (default_value);
- g_value_unset (default_value);
- g_free (default_value);
-
- return gss_option_get_value_by_index (sane,
- (SANE_Int) gs_param_spec_get_index (spec),
- type);
-}
+ g_type_class_add_private(o_class, sizeof(GSaneScannerPrivate));
-
-static GValue*
-gss_option_get_value_by_index (GSaneScanner *gss, SANE_Int n, GType type)
-{
- GSaneScannerPrivate *priv = GET_PRIVATE (gss);
- GValue *value = g_new0(GValue, 1);
- const SANE_Option_Descriptor *desc;
- SANE_Status status;
- SANE_Int i;
- void *v;
-
- desc = sane_get_option_descriptor (priv->handle, n);
-
- g_value_init (value, type);
- v = g_malloc0(desc->size);
- status = sane_control_option(priv->handle, n, SANE_ACTION_GET_VALUE, v, &i);
-
- switch (type) {
- case G_TYPE_BOOLEAN:
- g_value_set_boolean(value, *((gboolean*) v));
- break;
- case G_TYPE_INT:
- g_value_set_int(value, *((gint*) v));
- break;
- case G_TYPE_DOUBLE:
- g_value_set_double(value, SANE_UNFIX (*((SANE_Word*) v)));
- break;
- case G_TYPE_FLOAT:
- g_value_set_float(value, SANE_UNFIX (*((SANE_Word*) v)));
- break;
- case G_TYPE_STRING:
- g_value_set_string (value, g_strdup(v));
- break;
- default:
- g_warning ("%s: Can't retrieve value of type %s for option %s.",
- G_STRLOC,
- g_type_name(type),
- desc->name);
- break;
- }
-
- /*
- if (i & SANE_INFO_RELOAD_OPTIONS) {
- gs_debug ("Option reload needed for %s !", desc->name);
- }
- */
-
- return value;
+ o_class->constructor = gsane_scanner_constructor;
+ o_class->finalize = gsane_scanner_finalize;
+ o_class->get_property = gsane_scanner_get_property;
+ o_class->set_property = gsane_scanner_set_property;
+ g_object_class_install_property(o_class, GSANE_SCANNER_SANE_ID, g_param_spec_string("sane-id", "SANE ID", "SANE device id", NULL,G_PARAM_WRITABLE|G_PARAM_CONSTRUCT_ONLY));
+ g_object_class_install_property(o_class, GSANE_SCANNER_SANE_TYPE, g_param_spec_string("sane-type", "SANE Type", "SANE device type", NULL, G_PARAM_WRITABLE|G_PARAM_CONSTRUCT_ONLY));
}
-gpointer*
-gsane_scanner_get_meta_param(GSaneScanner *gss,
- gchar *name)
-{
- GSaneScannerPrivate *priv = GET_PRIVATE(gss);
- return g_hash_table_lookup (priv->meta_params, name);
-}
-/* returns TRUE if we need to reload options. */
-SANE_Int
-gsane_scanner_option_set_value (GSaneScanner *gss, GParamSpec *spec, GValue *value)
-{
- GValue *old;
- SANE_Int i, n = (SANE_Int) gs_param_spec_get_index (spec);
- SANE_Bool boolean;
- SANE_Word word;
- SANE_Status status;
- void *v = NULL;
- /* don't reset option to the same value */
- old = gsane_scanner_option_get_value (gss, spec);
- if (gs_param_values_cmp (spec, old, value) == 0)
- return 0;
-
- switch (G_VALUE_TYPE (value)) {
- case G_TYPE_BOOLEAN:
- boolean = g_value_get_boolean (value);
- v = &boolean;
- break;
- case G_TYPE_INT:
- word = g_value_get_int (value);
- v = &word;
- break;
- case G_TYPE_DOUBLE:
- word = SANE_FIX (g_value_get_double (value));
- v = &word;
- break;
- case G_TYPE_FLOAT:
- word = SANE_FIX (g_value_get_float (value));
- v = &word;
- break;
- case G_TYPE_STRING:
- v = g_value_dup_string (value);
- break;
- }
-
- gs_debug ("setting '%s' to %s",
- g_param_spec_get_name (spec),
- g_strdup_value_contents(value));
-
- status = sane_control_option (GET_PRIVATE (gss)->handle, n,
- SANE_ACTION_SET_VALUE, v, &i);
- return i;
-}
-
-
-static void
-gss_params_foreach_set_param (GParamSpec *spec, GSaneScanner *gss)
-{
- GSaneScannerPrivate *priv = GET_PRIVATE (gss);
- GValue * value, *value0;
- SANE_Int i = 0;
- MetaParam *mp = NULL;
-
- mp = g_param_spec_get_qdata (spec, GSANE_META_PARAM_QUARK);
-
- value = gnome_scan_settings_get (priv->settings,
- g_param_spec_get_name (spec));
-
- i = mp ? meta_param_set_value (mp, spec, priv->settings) : gsane_scanner_option_set_value (gss, spec, value);
-
- if (i & SANE_INFO_RELOAD_OPTIONS) {
- priv->reload = TRUE;
- }
-
- if (i & SANE_INFO_INEXACT) {
- value0 = mp ? meta_param_get_value (mp, spec) : gsane_scanner_option_get_value (gss, spec);
- if (value0)
- g_value_copy (value0, value);
- gnome_scan_settings_set (priv->settings,
- g_param_spec_get_name (spec),
- value);
- priv->changed = TRUE;
- gs_debug (" exact value = %s", g_strdup_value_contents (value));
- }
-}
-
-static void
-gss_params_foreach_update_param (GParamSpec *pspec, GSaneScanner *gss)
-{
- GSaneScannerPrivate *priv = GET_PRIVATE (gss);
- const SANE_Option_Descriptor *desc;
- guint flags = 0;
- guint n = gs_param_spec_get_index (pspec);
-
- desc = sane_get_option_descriptor(priv->handle, n);
-
- if (desc && SANE_OPTION_IS_ACTIVE (desc->cap)) {
- flags = flags | G_PARAM_WRITABLE;
- g_param_spec_set_qdata (pspec, GSANE_OPTION_DESC_QUARK, (gpointer) desc);
- }
-
- if (flags != pspec->flags) {
- gs_debug (G_STRLOC ": %s %sabled", g_param_spec_get_name (pspec),
- (flags & G_PARAM_WRITABLE ? "en" : "dis"));
- pspec->flags = flags;
- gnome_scan_plugin_params_changed (GNOME_SCAN_PLUGIN (gss), pspec);
- }
-}
-
-static void
-gss_mp_foreach_option_matches (const gchar *key, MetaParam *mp, GPtrArray* arg)
-{
- MetaParam **dest = g_ptr_array_index (arg, 1);
- GParamSpec *spec = g_ptr_array_index (arg, 2);
- if (gss_option_name_matches_array (spec,
- (const gchar**) meta_param_get_options_names (mp))) {
- *dest = mp;
- }
-}
-
-static void
-gss_mp_foreach_add_param (const gchar* key, MetaParam *mp, GSaneScanner *gss)
-{
- /* ask MetaParam to add its sub params to gss */
- meta_param_get_params (mp);
-}
Modified: trunk/modules/gsane-scanner.h
==============================================================================
--- trunk/modules/gsane-scanner.h (original)
+++ trunk/modules/gsane-scanner.h Thu Dec 11 21:21:11 2008
@@ -36,33 +36,28 @@
#define GNOME_IS_SCANNER_SANE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GSANE_TYPE_SCANNER))
#define GSANE_SCANNER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GSANE_TYPE_SCANNER, GSaneScannerClass))
-typedef struct _GSaneScannerClass GSaneScannerClass;
typedef struct _GSaneScanner GSaneScanner;
+typedef struct _GSaneScannerClass GSaneScannerClass;
+typedef struct _GSaneScannerPrivate GSaneScannerPrivate;
struct _GSaneScannerClass
{
- GnomeScanScannerClass parent_class;
+ GnomeScanScannerClass parent_class;
};
struct _GSaneScanner
{
- GnomeScanScanner parent_instance;
+ GnomeScanScanner parent_instance;
- /* wether the ADF is selected */
- gboolean adf;
+ /* whether the ADF is selected */
+ gboolean adf;
+ /*< private >*/
+ GSaneScannerPrivate* priv;
};
GType gsane_scanner_get_type (void) G_GNUC_CONST;
void gsane_scanner_register_type (GTypeModule *module);
-GnomeScanScanner *gsane_scanner_new (const SANE_Device *device);
-
-GValue* gsane_scanner_option_get_value (GSaneScanner *sane,
- GParamSpec *spec);
-SANE_Int gsane_scanner_option_set_value (GSaneScanner *gss,
- GParamSpec *spec,
- GValue *value);
-gpointer* gsane_scanner_get_meta_param(GSaneScanner *gss,
- gchar *name);
+GnomeScanScanner* gsane_scanner_new (const SANE_Device *device);
G_END_DECLS
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]