From 6e9c41a892ed0e0da326e0278b3221ce3f5713b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Frings-F=C3=BCrst?= Date: Mon, 6 Oct 2014 14:00:40 +0200 Subject: Initial import of sane-backends version 1.0.24-1.2 --- japi/ImageCanvas.java | 110 ++++ japi/ImageCanvasClient.java | 54 ++ japi/Jscanimage.java | 1166 +++++++++++++++++++++++++++++++++++++++++++ japi/Makefile.am | 47 ++ japi/Makefile.in | 738 +++++++++++++++++++++++++++ japi/README.JAVA | 55 ++ japi/Sane.c | 493 ++++++++++++++++++ japi/Sane.java | 144 ++++++ japi/SaneDevice.java | 55 ++ japi/SaneOption.java | 145 ++++++ japi/SaneParameters.java | 68 +++ japi/SaneRange.java | 53 ++ japi/ScanIt.java | 391 +++++++++++++++ japi/Test.java | 175 +++++++ 14 files changed, 3694 insertions(+) create mode 100644 japi/ImageCanvas.java create mode 100644 japi/ImageCanvasClient.java create mode 100644 japi/Jscanimage.java create mode 100644 japi/Makefile.am create mode 100644 japi/Makefile.in create mode 100644 japi/README.JAVA create mode 100644 japi/Sane.c create mode 100644 japi/Sane.java create mode 100644 japi/SaneDevice.java create mode 100644 japi/SaneOption.java create mode 100644 japi/SaneParameters.java create mode 100644 japi/SaneRange.java create mode 100644 japi/ScanIt.java create mode 100644 japi/Test.java (limited to 'japi') diff --git a/japi/ImageCanvas.java b/japi/ImageCanvas.java new file mode 100644 index 0000000..56cf34c --- /dev/null +++ b/japi/ImageCanvas.java @@ -0,0 +1,110 @@ +/* sane - Scanner Access Now Easy. + Copyright (C) 1997 Jeffrey S. Freedman + This file is part of the SANE package. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program 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 + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA. + + As a special exception, the authors of SANE give permission for + additional uses of the libraries contained in this release of SANE. + + The exception is that, if you link a SANE library with other files + to produce an executable, this does not by itself cause the + resulting executable to be covered by the GNU General Public + License. Your use of that executable is in no way restricted on + account of linking the SANE library code into it. + + This exception does not, however, invalidate any other reasons why + the executable file might be covered by the GNU General Public + License. + + If you submit changes to SANE to the maintainers to be included in + a subsequent release, you agree by submitting the changes that + those changes may be distributed with this exception intact. + + If you write modifications of your own for SANE, it is your choice + whether to permit this exception to apply to your modifications. + If you do not wish that, delete this exception notice. */ + +/** + ** ImageCanvas.java - A canvas that displays an image. + ** + ** Written: 11/4/97 - JSF + **/ + +import java.awt.Canvas; +import java.awt.Dimension; +import java.awt.Graphics; +import java.awt.Image; +import java.awt.image.ImageProducer; + +/* + * Here's a canvas that just shows an image. + */ + +public class ImageCanvas extends Canvas + { + Image image = null; // The image to display. + ImageCanvasClient client = null; // 1 client for now. + + /* + * Create with empty image. + */ + ImageCanvas() + { + } + + /* + * Create image from an image producer. + */ + void setImage(ImageProducer iprod, ImageCanvasClient c) + { + client = c; + image = createImage(iprod); + repaint(); + } + + /* + * Paint. + */ + public void paint(Graphics g) + { + System.out.println("In ImageCanvas.paint()"); + Dimension dim = getSize(); + g.drawRect(0, 0, dim.width - 1, dim.height - 1); + if (image != null) + { + g.drawImage(image, 1, 1, dim.width - 2, dim.height - 2, this); + } + } + + /* + * Image has been updated. + */ + public boolean imageUpdate(Image theimg, int infoflags, + int x, int y, int w, int h) + { + System.out.println("In imageUpdate()"); + boolean done = ((infoflags & (ERROR | FRAMEBITS | ALLBITS)) != 0); +// repaint(); + paint(getGraphics()); + if (done && client != null) // Tell client when done. + { + client.imageDone((infoflags & ERROR) != 0); + client = null; + } + return (!done); + } + } diff --git a/japi/ImageCanvasClient.java b/japi/ImageCanvasClient.java new file mode 100644 index 0000000..f9caebe --- /dev/null +++ b/japi/ImageCanvasClient.java @@ -0,0 +1,54 @@ +/* sane - Scanner Access Now Easy. + Copyright (C) 1997 Jeffrey S. Freedman + This file is part of the SANE package. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program 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 + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA. + + As a special exception, the authors of SANE give permission for + additional uses of the libraries contained in this release of SANE. + + The exception is that, if you link a SANE library with other files + to produce an executable, this does not by itself cause the + resulting executable to be covered by the GNU General Public + License. Your use of that executable is in no way restricted on + account of linking the SANE library code into it. + + This exception does not, however, invalidate any other reasons why + the executable file might be covered by the GNU General Public + License. + + If you submit changes to SANE to the maintainers to be included in + a subsequent release, you agree by submitting the changes that + those changes may be distributed with this exception intact. + + If you write modifications of your own for SANE, it is your choice + whether to permit this exception to apply to your modifications. + If you do not wish that, delete this exception notice. */ + +/** + ** ImageCanvasClient.java - A client of the canvas that displays an image. + ** + ** Written: 11/20/97 - JSF + **/ + +/* + * This interface lets its owner know when an image canvas is through + * being painted. + */ +interface ImageCanvasClient + { + void imageDone(boolean failed); // Image is complete. + } diff --git a/japi/Jscanimage.java b/japi/Jscanimage.java new file mode 100644 index 0000000..d3ab32d --- /dev/null +++ b/japi/Jscanimage.java @@ -0,0 +1,1166 @@ +/* sane - Scanner Access Now Easy. + Copyright (C) 1997 Jeffrey S. Freedman + This file is part of the SANE package. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program 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 + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA. + + As a special exception, the authors of SANE give permission for + additional uses of the libraries contained in this release of SANE. + + The exception is that, if you link a SANE library with other files + to produce an executable, this does not by itself cause the + resulting executable to be covered by the GNU General Public + License. Your use of that executable is in no way restricted on + account of linking the SANE library code into it. + + This exception does not, however, invalidate any other reasons why + the executable file might be covered by the GNU General Public + License. + + If you submit changes to SANE to the maintainers to be included in + a subsequent release, you agree by submitting the changes that + those changes may be distributed with this exception intact. + + If you write modifications of your own for SANE, it is your choice + whether to permit this exception to apply to your modifications. + If you do not wish that, delete this exception notice. */ + +/** + ** Jscanimage.java - Java scanner program using SANE. + ** + ** Written: 10/31/97 - JSF + **/ + +import java.awt.*; +import java.awt.event.*; +import java.util.*; +import java.awt.image.ImageConsumer; +import java.awt.image.ColorModel; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.text.NumberFormat; +import javax.swing.*; +import javax.swing.border.*; +import javax.swing.event.*; + +/* + * Main program. + */ +public class Jscanimage extends Frame implements WindowListener, + ActionListener, ItemListener, ImageCanvasClient + { + // + // Static data. + // + private static Sane sane; // The main class. + private static SaneDevice devList[];// List of devices. + // + // Instance data. + // + private Font font; // For dialog items. + private int saneHandle; // Handle of open device. + private ScanIt scanIt = null; // Does the actual scan. + // File to output to. + private FileOutputStream outFile = null; + private String outDir = null; // Stores dir. for output dialog. + private Vector controls; // Dialog components for SANE controls. + private double unitLength = 1; // # of mm for units to display + // (mm = 1, cm = 10, in = 25.4). + private ImageCanvas imageDisplay = null; + // "Scan", "Preview" buttons. + private JButton scanButton, previewButton; + private JButton browseButton; // For choosing output filename. + private JTextField outputField; // Field for output filename. + private MenuItem exitMenuItem; // Menu items. + private CheckboxMenuItem toolTipsMenuItem; + private CheckboxMenuItem mmMenuItem; + private CheckboxMenuItem cmMenuItem; + private CheckboxMenuItem inMenuItem; + + /* + * Main program. + */ + public static void main(String args[]) + { + if (!initSane()) // Initialize SANE. + return; + Jscanimage prog = new Jscanimage(); + prog.pack(); + prog.show(); + } + + /* + * Create main window. + */ + public Jscanimage() + { + super("SANE Scanimage"); + addWindowListener(this); + // Open SANE device. + saneHandle = initSaneDevice(devList[0].name); + if (saneHandle == 0) + System.exit(-1); + // Create scanner class. + scanIt = new ScanIt(sane, saneHandle); + init(); + } + + /* + * Clean up. + */ + public void finalize() + { + if (sane != null) + { + if (saneHandle != 0) + sane.close(saneHandle); + sane.exit(); + sane = null; + } + saneHandle = 0; + if (outFile != null) + { + try + { + outFile.close(); + } + catch (IOException e) + { } + outFile = null; + } + System.out.println("In finalize()"); + } + + /* + * Return info. + */ + public Sane getSane() + { return sane; } + public int getSaneHandle() + { return saneHandle; } + public double getUnitLength() + { return unitLength; } + + /* + * Initialize SANE. + */ + private static boolean initSane() + { + sane = new Sane(); + int version[] = new int[1]; // Array to get version #. + int status = sane.init(version); + if (status != Sane.STATUS_GOOD) + { + System.out.println("getDevices() failed. Status= " + status); + return (false); + } + // Get list of devices. + // Allocate room for 50. + devList = new SaneDevice[50]; + status = sane.getDevices(devList, false); + if (status != Sane.STATUS_GOOD) + { + System.out.println("getDevices() failed. Status= " + status); + return (false); + } + for (int i = 0; i < 50 && devList[i] != null; i++) + { + System.out.println("Device '" + devList[i].name + "' is a " + + devList[i].vendor + " " + devList[i].model + " " + + devList[i].type); + } + return (true); + } + + /* + * Open device. + * + * Output: Handle, or 0 if error. + */ + private int initSaneDevice(String name) + { + int handle[] = new int[1]; + // Open 1st device, for now. + int status = sane.open(name, handle); + if (status != Sane.STATUS_GOOD) + { + System.out.println("open() failed. Status= " + status); + return (0); + } + setTitle("SANE - " + name); + System.out.println("Open handle=" + handle[0]); + return (handle[0]); + } + + /* + * Add a labeled option to the main dialog. + */ + private void addLabeledOption(JPanel group, String title, Component opt, + GridBagConstraints c) + { + JLabel label = new JLabel(title); + c.gridwidth = GridBagConstraints.RELATIVE; + c.fill = GridBagConstraints.NONE; + c.anchor = GridBagConstraints.WEST; + c.weightx = .1; + group.add(label, c); + c.gridwidth = GridBagConstraints.REMAINDER; + c.fill = GridBagConstraints.HORIZONTAL; + c.weightx = .4; + group.add(opt, c); + } + + /* + * Get options for device. + */ + private boolean initSaneOptions() + { + JPanel group = null; + GridBagConstraints c = new GridBagConstraints(); + c.weightx = .4; + c.weighty = .4; + // Get # of device options. + int numDevOptions[] = new int[1]; + int status = sane.getControlOption(saneHandle, 0, numDevOptions, null); + if (status != Sane.STATUS_GOOD) + { + System.out.println("controlOption() failed. Status= " + + status); + return (false); + } + System.out.println("Number of device options=" + numDevOptions[0]); + // Do each option. + for (int i = 0; i < numDevOptions[0]; i++) + { + SaneOption opt = sane.getOptionDescriptor(saneHandle, i); + if (opt == null) + { + System.out.println("getOptionDescriptor() failed for " + + i); + continue; + } +/* + System.out.println("Option title: " + opt.title); + System.out.println("Option desc: " + opt.desc); + System.out.println("Option type: " + opt.type); + */ + String title; // Set up title. + if (opt.unit == SaneOption.UNIT_NONE) + title = opt.title; + else // Show units. + title = opt.title + " [" + + opt.unitString(unitLength) + ']'; + switch (opt.type) + { + case SaneOption.TYPE_GROUP: + // Group for a set of options. + group = new JPanel(new GridBagLayout()); + c.gridwidth = GridBagConstraints.REMAINDER; + c.fill = GridBagConstraints.BOTH; + c.anchor = GridBagConstraints.CENTER; + add(group, c); + group.setBorder(new TitledBorder(title)); + break; + case SaneOption.TYPE_BOOL: + // A checkbox. + SaneCheckBox cbox = new SaneCheckBox(opt.title, + this, i, opt.desc); + c.gridwidth = GridBagConstraints.REMAINDER; + c.fill = GridBagConstraints.NONE; + c.anchor = GridBagConstraints.WEST; + if (group != null) + group.add(cbox, c); + addControl(cbox); + break; + case SaneOption.TYPE_FIXED: + // Fixed-point value. + if (opt.size != 4) + break; // Not sure about this. + switch (opt.constraintType) + { + case SaneOption.CONSTRAINT_RANGE: + // A scale. + SaneSlider slider = new FixedSaneSlider( + opt.rangeConstraint.min, + opt.rangeConstraint.max, + opt.unit == SaneOption.UNIT_MM, + this, i, opt.desc); + addLabeledOption(group, title, slider, c); + addControl(slider); + break; + case SaneOption.CONSTRAINT_WORD_LIST: + // Select from a list. + SaneFixedBox list = new SaneFixedBox( + this, i, opt.desc); + addLabeledOption(group, title, list, c); + addControl(list); + break; + } + break; + case SaneOption.TYPE_INT: + // Integer value. + if (opt.size != 4) + break; // Not sure about this. + switch (opt.constraintType) + { + case SaneOption.CONSTRAINT_RANGE: + // A scale. + SaneSlider slider = new SaneSlider( + opt.rangeConstraint.min, + opt.rangeConstraint.max, + this, i, opt.desc); + addLabeledOption(group, title, slider, c); + addControl(slider); + break; + case SaneOption.CONSTRAINT_WORD_LIST: + // Select from a list. + SaneIntBox list = new SaneIntBox( + this, i, opt.desc); + addLabeledOption(group, title, list, c); + addControl(list); + break; + } + break; + case SaneOption.TYPE_STRING: + // Text entry or choice box. + switch (opt.constraintType) + { + case SaneOption.CONSTRAINT_STRING_LIST: + // Make a list. + SaneStringBox list = new SaneStringBox( + this, i, opt.desc); + addLabeledOption(group, title, list, c); + addControl(list); + break; + case SaneOption.CONSTRAINT_NONE: + SaneTextField tfield = new SaneTextField(16, + this, i, opt.desc); + addLabeledOption(group, title, tfield, c); + addControl(tfield); + break; + } + break; + case SaneOption.TYPE_BUTTON: + c.gridwidth = GridBagConstraints.REMAINDER; + c.fill = GridBagConstraints.HORIZONTAL; + c.anchor = GridBagConstraints.CENTER; + c.insets = new Insets(8, 4, 4, 4); + JButton btn = new SaneButton(title, this, i, opt.desc); + group.add(btn, c); + c.insets = null; + break; + default: + break; + } + } + return (true); + } + + /* + * Set up "Output" panel. + */ + private JPanel initOutputPanel() + { + JPanel panel = new JPanel(new GridBagLayout()); + GridBagConstraints c = new GridBagConstraints(); + // Want 1 row. + c.gridx = GridBagConstraints.RELATIVE; + c.gridy = 0; + c.anchor = GridBagConstraints.WEST; +// c.fill = GridBagConstraints.HORIZONTAL; + c.weightx = .4; + c.weighty = .4; + panel.setBorder(new TitledBorder("Output")); + panel.add(new Label("Filename"), c); + outputField = new JTextField("out.pnm", 16); + panel.add(outputField, c); + c.insets = new Insets(0, 8, 0, 0); + browseButton = new JButton("Browse"); + browseButton.addActionListener(this); + panel.add(browseButton, c); + return (panel); + } + + /* + * Initialize main window. + */ + private void init() + { + controls = new Vector(); // List of SaneComponent's. + // Try a light blue: + setBackground(new Color(140, 200, 255)); + // And a larger font. + font = new Font("Helvetica", Font.PLAIN, 12); + setFont(font); + initMenu(); + // Main panel will be 1 column. + setLayout(new GridBagLayout()); + GridBagConstraints c = new GridBagConstraints(); + c.gridwidth = GridBagConstraints.REMAINDER; + c.fill = GridBagConstraints.BOTH; + c.weightx = .4; + c.weighty = .4; + // Panel for output: + JPanel outputPanel = initOutputPanel(); + add(outputPanel, c); + initSaneOptions(); // Get SANE options, set up dialog. + initButtons(); // Put buttons at bottom. + } + + /* + * Add a control to the dialog and set its initial value. + */ + private void addControl(SaneComponent comp) + { + controls.addElement(comp); + comp.setFromControl(); // Get initial value. + } + + /* + * Reinitialize components from SANE controls. + */ + private void reinit() + { + Enumeration ctrls = controls.elements(); + while (ctrls.hasMoreElements()) // Do each control. + { + SaneComponent comp = (SaneComponent) ctrls.nextElement(); + comp.setFromControl(); + } + } + + /* + * Set up the menubar. + */ + private void initMenu() + { + MenuBar mbar = new MenuBar(); + Menu file = new Menu("File"); + mbar.add(file); + exitMenuItem = new MenuItem("Exit"); + exitMenuItem.addActionListener(this); + file.add(exitMenuItem); + Menu pref = new Menu("Preferences"); + mbar.add(pref); + toolTipsMenuItem = new CheckboxMenuItem("Show tooltips", true); + toolTipsMenuItem.addItemListener(this); + pref.add(toolTipsMenuItem); + Menu units = new Menu("Length unit"); + pref.add(units); + mmMenuItem = new CheckboxMenuItem("millimeters", true); + mmMenuItem.addItemListener(this); + units.add(mmMenuItem); + cmMenuItem = new CheckboxMenuItem("centimeters", false); + cmMenuItem.addItemListener(this); + units.add(cmMenuItem); + inMenuItem = new CheckboxMenuItem("inches", false); + inMenuItem.addItemListener(this); + units.add(inMenuItem); + setMenuBar(mbar); + } + + /* + * Set up buttons panel at very bottom. + */ + private void initButtons() + { + // Buttons are at bottom. + JPanel bottomPanel = new JPanel(new GridBagLayout()); + // Indent around buttons. + GridBagConstraints c = new GridBagConstraints(); + c.gridwidth = GridBagConstraints.REMAINDER; + c.insets = new Insets(8, 8, 8, 8); + c.weightx = .4; + c.weighty = .2; + c.fill = GridBagConstraints.HORIZONTAL; + add(bottomPanel, c); + c.weighty = c.weightx = .4; + c.fill = GridBagConstraints.BOTH; + c.gridwidth = c.gridheight = 1; + // Create image display box. + imageDisplay = new ImageCanvas(); + bottomPanel.add(imageDisplay, c); + // Put btns. to right in 1 column. + JPanel buttonsPanel = new JPanel(new GridLayout(0, 1, 8, 8)); + bottomPanel.add(buttonsPanel, c); + scanButton = new JButton("Scan"); + buttonsPanel.add(scanButton); + scanButton.addActionListener(this); + previewButton = new JButton("Preview Window"); + buttonsPanel.add(previewButton); + previewButton.addActionListener(this); + } + + /* + * Set a SANE integer option. + */ + public void setControlOption(int optNum, int val) + { + int [] info = new int[1]; + if (sane.setControlOption(saneHandle, optNum, + SaneOption.ACTION_SET_VALUE, val, info) + != Sane.STATUS_GOOD) + System.out.println("setControlOption() failed."); + checkOptionInfo(info[0]); + } + + /* + * Set a SANE text option. + */ + public void setControlOption(int optNum, String val) + { + int [] info = new int[1]; + if (sane.setControlOption(saneHandle, optNum, + SaneOption.ACTION_SET_VALUE, val, info) + != Sane.STATUS_GOOD) + System.out.println("setControlOption() failed."); + checkOptionInfo(info[0]); + } + + /* + * Check the 'info' word returned from setControlOption(). + */ + private void checkOptionInfo(int info) + { + // Does everything completely change? + if ((info & SaneOption.INFO_RELOAD_OPTIONS) != 0) + reinit(); + // Need to update status line? + if ((info & SaneOption.INFO_RELOAD_PARAMS) != 0) + ; // ++++++++FILL IN. + } + + /* + * Handle a user action. + */ + public void actionPerformed(ActionEvent e) + { + if (e.getSource() == scanButton) + { + System.out.println("Rescanning"); + // Get file name. + String fname = outputField.getText(); + if (fname == null || fname.length() == 0) + fname = "out.pnm"; + try + { + outFile = new FileOutputStream(fname); + } + catch (IOException oe) + { + System.out.println("Error creating file: " + fname); + outFile = null; + return; + } + // Disable "Scan" button. + scanButton.setEnabled(false); + scanIt.setOutputFile(outFile); + imageDisplay.setImage(scanIt, this); + } + else if (e.getSource() == browseButton) + { + File file; // For working with names. + FileDialog dlg = new FileDialog(this, "Output Filename", + FileDialog.SAVE); + if (outDir != null) // Set to last directory. + dlg.setDirectory(outDir); + // Get current name. + String fname = outputField.getText(); + if (fname != null) + { + file = new File(fname); + dlg.setFile(file.getName()); + String dname = file.getParent(); + if (dname != null) + dlg.setDirectory(outDir); + } + dlg.show(); // Wait for result. + fname = dlg.getFile(); + // Store dir. for next time. + outDir = dlg.getDirectory(); + if (fname != null) + { + file = new File(outDir, fname); + String curDir; + String fullName; + try + { + curDir = (new File(".")).getCanonicalPath(); + fullName = file.getCanonicalPath(); + // Not in current directory? + if (!curDir.equals( + (new File(fullName)).getParent())) + fname = fullName; + } + catch (IOException ex) + { curDir = "."; fname = file.getName(); } + outputField.setText(fname); + } + } + else if (e.getSource() == exitMenuItem) + { + finalize(); // Just to be safe. + System.exit(0); + } + } + + /* + * Handle checkable menu items. + */ + public void itemStateChanged(ItemEvent e) + { + if (e.getSource() == mmMenuItem) + { // Wants mm. + unitLength = 1; + if (e.getStateChange() == ItemEvent.SELECTED) + { + cmMenuItem.setState(false); + inMenuItem.setState(false); + reinit(); // Re-display controls. + } + else // Don't let him deselect. + mmMenuItem.setState(true); + } + if (e.getSource() == cmMenuItem) + { // Wants cm. + unitLength = 10; + if (e.getStateChange() == ItemEvent.SELECTED) + { + mmMenuItem.setState(false); + inMenuItem.setState(false); + reinit(); // Re-display controls. + } + else + cmMenuItem.setState(true); + } + if (e.getSource() == inMenuItem) + { // Wants inches. + unitLength = 25.4; + if (e.getStateChange() == ItemEvent.SELECTED) + { + mmMenuItem.setState(false); + cmMenuItem.setState(false); + reinit(); // Re-display controls. + } + else // Don't let him deselect. + inMenuItem.setState(true); + } + } + + /* + * Scan is complete. + */ + public void imageDone(boolean error) + { + if (error) + System.out.println("Scanning error."); + if (outFile != null) // Close file. + try + { + outFile.close(); + } + catch (IOException e) + { } + scanButton.setEnabled(true); // Can scan again. + } + + /* + * Default window event handlers. + */ + public void windowClosed(WindowEvent event) + { + finalize(); // Just to be safe. + } + public void windowDeiconified(WindowEvent event) { } + public void windowIconified(WindowEvent event) { } + public void windowActivated(WindowEvent event) { } + public void windowDeactivated(WindowEvent event) { } + public void windowOpened(WindowEvent event) { } + // Handle closing event. + public void windowClosing(WindowEvent event) + { + finalize(); // Just to be safe. + System.exit(0); + } + } + +/* + * Interface for our dialog controls. + */ +interface SaneComponent + { + public void setFromControl(); // Ask SANE control for current value. + } + +/* + * A checkbox in our dialog. + */ +class SaneCheckBox extends JCheckBox implements ActionListener, + SaneComponent + { + private Jscanimage dialog; // That which created us. + private int optNum; // Option #. + + /* + * Create with given state. + */ + public SaneCheckBox(String title, Jscanimage dlg, int opt, String tip) + { + super(title, false); + dialog = dlg; + optNum = opt; + // Set tool tip. + if (tip != null && tip.length() != 0) + super.setToolTipText(tip); + addActionListener(this); // Listen to ourself. + } + + /* + * Update Sane device option with current setting. + */ + public void actionPerformed(ActionEvent e) + { + System.out.println("In SaneCheckBox::actionPerformed()"); + int val = isSelected() ? 1 : 0; + dialog.setControlOption(optNum, val); + } + + /* + * Update from Sane control's value. + */ + public void setFromControl() + { + int [] val = new int[1]; + if (dialog.getSane().getControlOption( + dialog.getSaneHandle(), optNum, val, null) + == Sane.STATUS_GOOD) + setSelected(val[0] != 0); + } + } + +/* + * A slider in our dialog. This base class handles integer ranges. + * It consists of a slider and a label which shows the current value. + */ +class SaneSlider extends JPanel implements SaneComponent, ChangeListener + { + protected Jscanimage dialog; // That which created us. + protected int optNum; // Option #. + protected JSlider slider; // The slider itself. + protected JLabel label; // Shows current value. + + /* + * Create with given state. + */ + public SaneSlider(int min, int max, Jscanimage dlg, int opt, String tip) + { + super(new GridBagLayout()); // Create panel. + dialog = dlg; + optNum = opt; + GridBagConstraints c = new GridBagConstraints(); + // Want 1 row. + c.gridx = GridBagConstraints.RELATIVE; + c.gridy = 0; + c.anchor = GridBagConstraints.CENTER; + c.fill = GridBagConstraints.HORIZONTAL; + c.weighty = .8; + c.weightx = .2; // Give less weight to value label. + label = new JLabel("00", SwingConstants.RIGHT); + add(label, c); + c.weightx = .8; // Give most weight to slider. + c.fill = GridBagConstraints.HORIZONTAL; + slider = new JSlider(JSlider.HORIZONTAL, min, max, + min + (max - min)/2); + add(slider, c); + // Set tool tip. + if (tip != null && tip.length() != 0) + super.setToolTipText(tip); + slider.addChangeListener(this); // Listen to ourself. + } + + /* + * Update Sane device option. + */ + public void stateChanged(ChangeEvent e) + { + int val = slider.getValue(); + label.setText(String.valueOf(val)); + dialog.setControlOption(optNum, val); + } + + /* + * Update from Sane control's value. + */ + public void setFromControl() + { + int [] val = new int[1]; // Get current SANE control value. + if (dialog.getSane().getControlOption( + dialog.getSaneHandle(), optNum, val, null) + == Sane.STATUS_GOOD) + { + slider.setValue(val[0]); + label.setText(String.valueOf(val[0])); + } + } + } + +/* + * A slider with fixed-point values: + */ +class FixedSaneSlider extends SaneSlider + { + private static final int SCALE_MIN = -32000; + private static final int SCALE_MAX = 32000; + double min, max; // Min, max in floating-point. + boolean optMM; // Option is in millimeters, so should + // be scaled to user's pref. + private NumberFormat format; // For printing label. + /* + * Create with given fixed-point range. + */ + public FixedSaneSlider(int fixed_min, int fixed_max, boolean mm, + Jscanimage dlg, int opt, String tip) + { + // Create with large integer range. + super(SCALE_MIN, SCALE_MAX, dlg, opt, tip); + format = NumberFormat.getInstance(); + // For now, show 1 decimal point. + format.setMinimumFractionDigits(1); + format.setMaximumFractionDigits(1); + // Store actual range. + min = dlg.getSane().unfix(fixed_min); + max = dlg.getSane().unfix(fixed_max); + optMM = mm; + } + + /* + * Update Sane device option. + */ + public void stateChanged(ChangeEvent e) + { + double val = (double) slider.getValue(); + // Convert to actual control scale. + val = min + ((val - SCALE_MIN)/(SCALE_MAX - SCALE_MIN)) * (max - min); + label.setText(format.format(optMM ? + val/dialog.getUnitLength() : val)); + dialog.setControlOption(optNum, dialog.getSane().fix(val)); + } + + /* + * Update from Sane control's value. + */ + public void setFromControl() + { + int [] ival = new int[1]; // Get current SANE control value. + if (dialog.getSane().getControlOption( + dialog.getSaneHandle(), optNum, ival, null) + == Sane.STATUS_GOOD) + { + double val = dialog.getSane().unfix(ival[0]); + // Show value with user's pref. + label.setText(format.format(optMM ? + val/dialog.getUnitLength() : val)); + val = SCALE_MIN + ((val - min)/(max - min)) * + (SCALE_MAX - SCALE_MIN); + slider.setValue((int) val); + } + } + } + +/* + * A Button in our dialog. + */ +class SaneButton extends JButton implements ActionListener + { + private Jscanimage dialog; // That which created us. + private int optNum; // Option #. + + /* + * Create with given state. + */ + public SaneButton(String title, Jscanimage dlg, int opt, String tip) + { + super(title); + dialog = dlg; + optNum = opt; + // Set tool tip. + if (tip != null && tip.length() != 0) + super.setToolTipText(tip); + addActionListener(this); // Listen to ourself. + } + + /* + * Update Sane device option. + */ + public void actionPerformed(ActionEvent e) + { + dialog.setControlOption(optNum, 0); + System.out.println("In SaneButton::actionPerformed()"); + } + } + +/* + * A combo-box for showing a list of items. + */ +abstract class SaneComboBox extends JComboBox + implements SaneComponent, ItemListener + { + protected Jscanimage dialog; // That which created us. + protected int optNum; // Option #. + + /* + * Create it. + */ + public SaneComboBox(Jscanimage dlg, int opt, String tip) + { + dialog = dlg; + optNum = opt; + // Set tool tip. + if (tip != null && tip.length() != 0) + super.setToolTipText(tip); + addItemListener(this); + } + + /* + * Select desired item by its text. + */ + protected void select(String text) + { + int cnt = getItemCount(); + for (int i = 0; i < cnt; i++) + if (text.equals(getItemAt(i))) + { + setSelectedIndex(i); + break; + } + } + + abstract public void setFromControl(); + abstract public void itemStateChanged(ItemEvent e); + } + +/* + * A list of strings. + */ +class SaneStringBox extends SaneComboBox + { + + /* + * Create it. + */ + public SaneStringBox(Jscanimage dlg, int opt, String tip) + { + super(dlg, opt, tip); + } + + /* + * Update from Sane control's value. + */ + public void setFromControl() + { + // Let's get the whole list. + SaneOption opt = dialog.getSane().getOptionDescriptor( + dialog.getSaneHandle(), optNum); + if (opt == null) + return; + removeAllItems(); // Clear list. + // Go through list from option. + for (int i = 0; opt.stringListConstraint[i] != null; i++) + addItem(opt.stringListConstraint[i]); + // Get value. + byte buf[] = new byte[opt.size + 1]; + if (dialog.getSane().getControlOption( + dialog.getSaneHandle(), optNum, buf, null) + == Sane.STATUS_GOOD) + select(new String(buf)); + } + + /* + * An item was selected. + */ + public void itemStateChanged(ItemEvent e) + { + // Get current selection. + String val = (String) getSelectedItem(); + if (val != null) + dialog.setControlOption(optNum, val); + } + } + +/* + * A list of integers. + */ +class SaneIntBox extends SaneComboBox + { + + /* + * Create it. + */ + public SaneIntBox(Jscanimage dlg, int opt, String tip) + { + super(dlg, opt, tip); + } + + /* + * Update from Sane control's value. + */ + public void setFromControl() + { + // Let's get the whole list. + SaneOption opt = dialog.getSane().getOptionDescriptor( + dialog.getSaneHandle(), optNum); + if (opt == null) + return; + removeAllItems(); // Clear list. + // Go through list from option. + int cnt = opt.wordListConstraint[0]; + for (int i = 0; i < cnt; i++) + addItem(String.valueOf(opt.wordListConstraint[i + 1])); + // Get value. + int [] val = new int[1]; // Get current SANE control value. + if (dialog.getSane().getControlOption( + dialog.getSaneHandle(), optNum, val, null) + == Sane.STATUS_GOOD) + select(String.valueOf(val[0])); + } + + /* + * An item was selected. + */ + public void itemStateChanged(ItemEvent e) + { + // Get current selection. + String val = (String) getSelectedItem(); + if (val != null) + try + { + Integer v = Integer.valueOf(val); + dialog.setControlOption(optNum, v.intValue()); + } + catch (NumberFormatException ex) { } + } + } + +/* + * A list of fixed-point floating point numbers. + */ +class SaneFixedBox extends SaneComboBox + { + + /* + * Create it. + */ + public SaneFixedBox(Jscanimage dlg, int opt, String tip) + { + super(dlg, opt, tip); + } + + /* + * Update from Sane control's value. + */ + public void setFromControl() + { + // Let's get the whole list. + SaneOption opt = dialog.getSane().getOptionDescriptor( + dialog.getSaneHandle(), optNum); + if (opt == null) + return; + removeAllItems(); // Clear list. + // Go through list from option. + int cnt = opt.wordListConstraint[0]; + for (int i = 0; i < cnt; i++) + addItem(String.valueOf(dialog.getSane().unfix( + opt.wordListConstraint[i + 1]))); + // Get value. + int [] val = new int[1]; // Get current SANE control value. + if (dialog.getSane().getControlOption( + dialog.getSaneHandle(), optNum, val, null) + == Sane.STATUS_GOOD) + select(String.valueOf(dialog.getSane().unfix(val[0]))); + } + + /* + * An item was selected. + */ + public void itemStateChanged(ItemEvent e) + { + // Get current selection. + String val = (String) getSelectedItem(); + if (val != null) + try + { + Double v = Double.valueOf(val); + dialog.setControlOption(optNum, + dialog.getSane().fix(v.doubleValue())); + } + catch (NumberFormatException ex) { } + } + } + +/* + * A text-entry field in our dialog. + */ +class SaneTextField extends JTextField implements SaneComponent + { + private Jscanimage dialog; // That which created us. + private int optNum; // Option #. + + /* + * Create with given state. + */ + public SaneTextField(int width, Jscanimage dlg, int opt, String tip) + { + super(width); // Set initial text, # chars. + dialog = dlg; + optNum = opt; + // Set tool tip. + if (tip != null && tip.length() != 0) + super.setToolTipText(tip); + } + + /* + * Update Sane device option with current setting when user types. + */ + public void processKeyEvent(KeyEvent e) + { + super.processKeyEvent(e); // Handle it normally. + if (e.getID() != KeyEvent.KEY_TYPED) + return; // Just do it after keystroke. + String userText = getText(); // Get what's there, & save copy. + String newText = new String(userText); + dialog.setControlOption(optNum, newText); + if (!newText.equals(userText)) // Backend may have changed it. + setText(newText); + } + + /* + * Update from Sane control's value. + */ + public void setFromControl() + { + byte buf[] = new byte[1024]; + if (dialog.getSane().getControlOption( + dialog.getSaneHandle(), optNum, buf, null) + == Sane.STATUS_GOOD) + { + String text = new String(buf); + System.out.println("SaneTextField::setFromControl: " + text); + setText(text); // Set text in field. + setScrollOffset(0); + } + } + } diff --git a/japi/Makefile.am b/japi/Makefile.am new file mode 100644 index 0000000..5d66e82 --- /dev/null +++ b/japi/Makefile.am @@ -0,0 +1,47 @@ +## Makefile.am -- an automake template for Makefile.in file +## Copyright (C) 2009 Chris Bagwell and Sane Developers. +## +## This file is part of the "Sane" build infra-structure. See +## included LICENSE file for license information. + +# +# Makefile for a Java project with native methods. +# + +V_MAJOR = @V_MAJOR@ +V_MINOR = @V_MINOR@ +V_REV = @V_REV@ + +JAVAROOT=. +CLASSPATH_ENV=. +JAVAH=javah -jni -cp $(CLASSPATH_ENV) + +# We'll need something in 'configure' for the Java includes. +AM_CPPFLAGS = -I. -I$(srcdir) -I$(top_builddir)/include \ + -I$(top_srcdir)/include -I${JDK_HOME}/include \ + -I${JDK_HOME}/include/genunix +AM_LDFLAGS = @STRICT_LDFLAGS@ -version-number $(V_MAJOR):$(V_MINOR):$(VREV) + +JAVA_SRC = SaneDevice.java SaneOption.java SaneRange.java\ + Sane.java SaneParameters.java ScanIt.java \ + ImageCanvas.java ImageCanvasClient.java \ + Test.java Jscanimage.java + +dist_noinst_JAVA = $(JAVA_SRC) + +LIBSANE = ../backend/libsane.la + +EXTRA_DIST = Makefile.in README.JAVA + +lib_LTLIBRARIES = libsanej.la + +BUILT_SOURCES = Sane.h +CLEANFILES = Sane.h +nodist_libsanej_la_SOURCES = Sane.h +libsanej_la_SOURCES = Sane.c +libsanej_la_LIBADD = $(LIBSANE) + +# Make sure that java classes get created before create Sane.h +Sane.h: classdist_noinst.stamp + $(JAVAH) Sane + diff --git a/japi/Makefile.in b/japi/Makefile.in new file mode 100644 index 0000000..550bd8d --- /dev/null +++ b/japi/Makefile.in @@ -0,0 +1,738 @@ +# Makefile.in generated by automake 1.13.4 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2013 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +# +# Makefile for a Java project with native methods. +# + +VPATH = @srcdir@ +am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = japi +DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ + $(top_srcdir)/mkinstalldirs $(top_srcdir)/depcomp \ + $(dist_noinst_JAVA) +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/ltoptions.m4 \ + $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ + $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/acinclude.m4 \ + $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/byteorder.m4 \ + $(top_srcdir)/m4/stdint.m4 $(top_srcdir)/configure.in +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_HEADER = $(top_builddir)/include/sane/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__installdirs = "$(DESTDIR)$(libdir)" +LTLIBRARIES = $(lib_LTLIBRARIES) +libsanej_la_DEPENDENCIES = $(LIBSANE) +am_libsanej_la_OBJECTS = Sane.lo +nodist_libsanej_la_OBJECTS = +libsanej_la_OBJECTS = $(am_libsanej_la_OBJECTS) \ + $(nodist_libsanej_la_OBJECTS) +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include/sane +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(libsanej_la_SOURCES) $(nodist_libsanej_la_SOURCES) +DIST_SOURCES = $(libsanej_la_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +JAVAC = javac +am__java_sources = $(dist_noinst_JAVA) +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +ALLOCA = @ALLOCA@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AVAHI_CFLAGS = @AVAHI_CFLAGS@ +AVAHI_LIBS = @AVAHI_LIBS@ +AWK = @AWK@ +BACKENDS = @BACKENDS@ +BACKEND_CONFS_ENABLED = @BACKEND_CONFS_ENABLED@ +BACKEND_LIBS_ENABLED = @BACKEND_LIBS_ENABLED@ +BACKEND_MANS_ENABLED = @BACKEND_MANS_ENABLED@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DISTCLEAN_FILES = @DISTCLEAN_FILES@ +DLLTOOL = @DLLTOOL@ +DL_LIBS = @DL_LIBS@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +DVIPS = @DVIPS@ +DYNAMIC_FLAG = @DYNAMIC_FLAG@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GPHOTO2_CPPFLAGS = @GPHOTO2_CPPFLAGS@ +GPHOTO2_LDFLAGS = @GPHOTO2_LDFLAGS@ +GPHOTO2_LIBS = @GPHOTO2_LIBS@ +GREP = @GREP@ +HAVE_GPHOTO2 = @HAVE_GPHOTO2@ +IEEE1284_LIBS = @IEEE1284_LIBS@ +INCLUDES = @INCLUDES@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_LOCKPATH = @INSTALL_LOCKPATH@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +JPEG_LIBS = @JPEG_LIBS@ +LATEX = @LATEX@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIBUSB_1_0_CFLAGS = @LIBUSB_1_0_CFLAGS@ +LIBUSB_1_0_LIBS = @LIBUSB_1_0_LIBS@ +LIBV4L_CFLAGS = @LIBV4L_CFLAGS@ +LIBV4L_LIBS = @LIBV4L_LIBS@ +LINKER_RPATH = @LINKER_RPATH@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LOCKPATH_GROUP = @LOCKPATH_GROUP@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAKEINDEX = @MAKEINDEX@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MATH_LIB = @MATH_LIB@ +MKDIR_P = @MKDIR_P@ +MSGFMT = @MSGFMT@ +MSGMERGE = @MSGMERGE@ +NM = @NM@ +NMEDIT = @NMEDIT@ +NUMBER_VERSION = @NUMBER_VERSION@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +PRELOADABLE_BACKENDS = @PRELOADABLE_BACKENDS@ +PRELOADABLE_BACKENDS_ENABLED = @PRELOADABLE_BACKENDS_ENABLED@ +PTHREAD_LIBS = @PTHREAD_LIBS@ +RANLIB = @RANLIB@ +RESMGR_LIBS = @RESMGR_LIBS@ +SANEI_SANEI_JPEG_LO = @SANEI_SANEI_JPEG_LO@ +SANE_CONFIG_PATH = @SANE_CONFIG_PATH@ +SCSI_LIBS = @SCSI_LIBS@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +SNMP_CONFIG_PATH = @SNMP_CONFIG_PATH@ +SOCKET_LIBS = @SOCKET_LIBS@ +STRICT_LDFLAGS = @STRICT_LDFLAGS@ +STRIP = @STRIP@ +SYSLOG_LIBS = @SYSLOG_LIBS@ +SYSTEMD_LIBS = @SYSTEMD_LIBS@ +TIFF_LIBS = @TIFF_LIBS@ +USB_LIBS = @USB_LIBS@ +VERSION = @VERSION@ +V_MAJOR = @V_MAJOR@ +V_MINOR = @V_MINOR@ +V_REV = @V_REV@ +XGETTEXT = @XGETTEXT@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +configdir = @configdir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +effective_target = @effective_target@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +locksanedir = @locksanedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +JAVAROOT = . +CLASSPATH_ENV = . +JAVAH = javah -jni -cp $(CLASSPATH_ENV) + +# We'll need something in 'configure' for the Java includes. +AM_CPPFLAGS = -I. -I$(srcdir) -I$(top_builddir)/include \ + -I$(top_srcdir)/include -I${JDK_HOME}/include \ + -I${JDK_HOME}/include/genunix + +AM_LDFLAGS = @STRICT_LDFLAGS@ -version-number $(V_MAJOR):$(V_MINOR):$(VREV) +JAVA_SRC = SaneDevice.java SaneOption.java SaneRange.java\ + Sane.java SaneParameters.java ScanIt.java \ + ImageCanvas.java ImageCanvasClient.java \ + Test.java Jscanimage.java + +dist_noinst_JAVA = $(JAVA_SRC) +LIBSANE = ../backend/libsane.la +EXTRA_DIST = Makefile.in README.JAVA +lib_LTLIBRARIES = libsanej.la +BUILT_SOURCES = Sane.h +CLEANFILES = Sane.h +nodist_libsanej_la_SOURCES = Sane.h +libsanej_la_SOURCES = Sane.c +libsanej_la_LIBADD = $(LIBSANE) +all: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu japi/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu japi/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +install-libLTLIBRARIES: $(lib_LTLIBRARIES) + @$(NORMAL_INSTALL) + @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ + list2=; for p in $$list; do \ + if test -f $$p; then \ + list2="$$list2 $$p"; \ + else :; fi; \ + done; \ + test -z "$$list2" || { \ + echo " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \ + } + +uninstall-libLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \ + done + +clean-libLTLIBRARIES: + -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) + @list='$(lib_LTLIBRARIES)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + test -z "$$locs" || { \ + echo rm -f $${locs}; \ + rm -f $${locs}; \ + } + +libsanej.la: $(libsanej_la_OBJECTS) $(libsanej_la_DEPENDENCIES) $(EXTRA_libsanej_la_DEPENDENCIES) + $(AM_V_CCLD)$(LINK) -rpath $(libdir) $(libsanej_la_OBJECTS) $(libsanej_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Sane.Plo@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +classnoinst.stamp: $(am__java_sources) + @list1='$?'; list2=; if test -n "$$list1"; then \ + for p in $$list1; do \ + if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ + list2="$$list2 $$d$$p"; \ + done; \ + echo '$(CLASSPATH_ENV) $(JAVAC) -d $(JAVAROOT) $(AM_JAVACFLAGS) $(JAVACFLAGS) '"$$list2"; \ + $(CLASSPATH_ENV) $(JAVAC) -d $(JAVAROOT) $(AM_JAVACFLAGS) $(JAVACFLAGS) $$list2; \ + else :; fi + echo timestamp > $@ + +clean-noinstJAVA: + -rm -f *.class classnoinst.stamp + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) check-am +all-am: Makefile $(LTLIBRARIES) classnoinst.stamp +installdirs: + for dir in "$(DESTDIR)$(libdir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." + -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) +clean: clean-am + +clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \ + clean-noinstJAVA mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: install-libLTLIBRARIES + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-libLTLIBRARIES + +.MAKE: all check install install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ + clean-libLTLIBRARIES clean-libtool clean-noinstJAVA \ + cscopelist-am ctags ctags-am distclean distclean-compile \ + distclean-generic distclean-libtool distclean-tags distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-libLTLIBRARIES \ + install-man install-pdf install-pdf-am install-ps \ + install-ps-am install-strip installcheck installcheck-am \ + installdirs maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ + uninstall-am uninstall-libLTLIBRARIES + + +# Make sure that java classes get created before create Sane.h +Sane.h: classdist_noinst.stamp + $(JAVAH) Sane + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/japi/README.JAVA b/japi/README.JAVA new file mode 100644 index 0000000..4c838f4 --- /dev/null +++ b/japi/README.JAVA @@ -0,0 +1,55 @@ +-- +12/17/97 + +Most of Jscanimage's main dialog is coded, but only tested with PNM (which +means most of the newly supported option types haven't been tried yet). +Scanning (with PNM) does seem to work, although large files definitely take +longer in JAVA then with "xscanimage". + +Main things left to do: + 1. Provide the "preview" dialog. + 2. Try it out with a real scanner, especially with large images. + 3. Try it on a platform other than Linux. + +-- +11/18/97 + +This snapshot contains a partially functional "Jscanimage", which is intended +to be a Java clone of "xscanimage". Only some of the controls are implemented +(sliders, check-boxes, text-entry), and I've only tested it using small images +with the "pnm" backend; but, it does seem to be functional, and to output .pnm +files. + +There are also some small changes to the Java API. + +To do (at the least): + 1. Handle "word list" controls. + 2. Handle "browse" button for file selection. + 3. Provide pull-down menus for choosing length units, and use them. + 4. Provide the "preview" dialog. + 5. Try it out with a real scanner, especially with large images. + 6. Try it on a platform other than Linux. + + -- Jeff + +-- +10/17/97 + +NOTE: To build the Java interface, you have to cd into this directory +and type "make" (after running configure in the top-level directory). + + --david +-- +This is my first pass at creating a Java API for SANE. It requires JDK 1.1.x, +as it uses the new JNI for creating native methods. + +This is definitely not 100% pure Java, as it's really just a set of wrappers +which call the actual SANE backend routines. It's also very preliminary, so +feel free to suggest changes to the interface or class definitions. + +The 'install' installs the shared library (libsanej.*), but I'm not sure yet +what to do with the generated Java class files. So for now, you should be +able to run the test program after installation by typing "java Test" within +the "japi" directory. + +-- Jeff Freedman (jsf@hevanet.com) diff --git a/japi/Sane.c b/japi/Sane.c new file mode 100644 index 0000000..1ddb4fc --- /dev/null +++ b/japi/Sane.c @@ -0,0 +1,493 @@ +/* sane - Scanner Access Now Easy. + Copyright (C) 1997 Jeffrey S. Freedman + This file is part of the SANE package. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program 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 + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA. + + As a special exception, the authors of SANE give permission for + additional uses of the libraries contained in this release of SANE. + + The exception is that, if you link a SANE library with other files + to produce an executable, this does not by itself cause the + resulting executable to be covered by the GNU General Public + License. Your use of that executable is in no way restricted on + account of linking the SANE library code into it. + + This exception does not, however, invalidate any other reasons why + the executable file might be covered by the GNU General Public + License. + + If you submit changes to SANE to the maintainers to be included in + a subsequent release, you agree by submitting the changes that + those changes may be distributed with this exception intact. + + If you write modifications of your own for SANE, it is your choice + whether to permit this exception to apply to your modifications. + If you do not wish that, delete this exception notice. */ + +/** + ** Sane.c - Native methods for the SANE Java API. + ** + ** Written: 10/9/97 - JSF + **/ + +#include "Sane.h" +#include +#include + +#include /* Debugging */ + +#ifdef __cplusplus +extern "C" { +#endif +/* + * Class: Sane + * Method: init + * Signature: ([I)I + */ +JNIEXPORT jint JNICALL Java_Sane_init + (JNIEnv *env, jobject jobj, jintArray versionCode) + { + jsize len; /* Gets array length. */ + jint *versionCodeBody; /* Gets ->array. */ + SANE_Int version; /* Gets version. */ + SANE_Status status; /* Get SANE return. */ + + status = sane_init(&version, 0); + len = (*env)->GetArrayLength(env, versionCode); + versionCodeBody = (*env)->GetIntArrayElements(env, versionCode, 0); + if (len > 0) /* Return version. */ + versionCodeBody[0] = version; + (*env)->ReleaseIntArrayElements(env, versionCode, versionCodeBody, 0); + return (status); + } +/* + * Class: Sane + * Method: exit + * Signature: ()V + */ +JNIEXPORT void JNICALL Java_Sane_exit + (JNIEnv *env, jobject jobj) + { + sane_exit(); + } + + +/* + * Class: Sane + * Method: getDevices + * Signature: ([LSaneDevice;Z)I + */ +JNIEXPORT jint JNICALL Java_Sane_getDevicesNative + (JNIEnv *env, jobject jobj, jobjectArray devList, jboolean localOnly) + { + /* Gets device list. */ + const SANE_Device **device_list; + SANE_Status status; /* Gets status. */ + int devListLen; /* Gets length of devList. */ + jobject devObj; /* Gets each SaneDevice object. */ + jclass devClass; /* Gets SaneDevice class. */ + jfieldID fid; /* Gets each field ID. */ + int i; + + /* Get the list. */ + status = sane_get_devices(&device_list, localOnly); + if (status != SANE_STATUS_GOOD) + return (status); + /* Get length of Java array. */ + devListLen = (*env)->GetArrayLength(env, devList); + /* Return devices to user. */ + for (i = 0; i < devListLen - 1 && device_list[i]; i++) + { + /* Get Java object, class. */ + devObj = (*env)->GetObjectArrayElement(env, devList, i); + devClass = (*env)->GetObjectClass(env, devObj); + /* Fill in each member. */ + fid = (*env)->GetFieldID(env, devClass, "name", + "Ljava/lang/String;"); + (*env)->SetObjectField(env, devObj, fid, + (*env)->NewStringUTF(env, device_list[i]->name)); + fid = (*env)->GetFieldID(env, devClass, "vendor", + "Ljava/lang/String;"); + (*env)->SetObjectField(env, devObj, fid, + (*env)->NewStringUTF(env, device_list[i]->vendor)); + fid = (*env)->GetFieldID(env, devClass, "model", + "Ljava/lang/String;"); + (*env)->SetObjectField(env, devObj, fid, + (*env)->NewStringUTF(env, device_list[i]->model)); + fid = (*env)->GetFieldID(env, devClass, "type", + "Ljava/lang/String;"); + (*env)->SetObjectField(env, devObj, fid, + (*env)->NewStringUTF(env, device_list[i]->type)); + } + /* End list with a null. */ + (*env)->SetObjectArrayElement(env, devList, i, 0); + return (status); + } + +/* + * Class: Sane + * Method: open + * Signature: (Ljava/lang/String;[J)I + */ +JNIEXPORT jint JNICALL Java_Sane_open + (JNIEnv *env, jobject jobj, jstring deviceName, jintArray handle) + { + SANE_Handle sane_handle; /* Gets handle. */ + jint s_handle; + const char *device_name; /* Gets dev. name. */ + int status; /* Gets return code. */ + + device_name = (*env)->GetStringUTFChars(env, deviceName, 0); + /* Open it. */ + status = sane_open(device_name, &sane_handle); + (*env)->ReleaseStringUTFChars(env, deviceName, device_name); + /* Return handle. */ + s_handle = (jint) sane_handle; + (*env)->SetIntArrayRegion(env, handle, 0, 1, &s_handle); + return (status); + } + +/* + * Class: Sane + * Method: close + * Signature: (J)V + */ +JNIEXPORT void JNICALL Java_Sane_close + (JNIEnv *env, jobject jobj, jint handle) + { + sane_close((SANE_Handle) handle); + } + +/* + * Class: Sane + * Method: getOptionNative + * Signature: (IILSaneOption;)V + */ +JNIEXPORT void JNICALL Java_Sane_getOptionNative + (JNIEnv *env, jobject jobj, jint handle, jint option, jobject optObj) + { + jclass optClass; /* Gets its class. */ + jfieldID fid; /* Gets each field ID. */ + jstring str; /* Gets strings. */ + + /* Get info from sane. */ + const SANE_Option_Descriptor *sopt = sane_get_option_descriptor( + (SANE_Handle) handle, option); + /* Get class info. */ + optClass = (*env)->GetObjectClass(env, optObj); + /* Fill in each member. */ + fid = (*env)->GetFieldID(env, optClass, "name", "Ljava/lang/String;"); + if (!sopt) /* Failed. */ + { /* Set name to null. */ + (*env)->SetObjectField(env, optObj, fid, 0); + return; + } + /* Return name. */ + (*env)->SetObjectField(env, optObj, fid, + (*env)->NewStringUTF(env, sopt->name)); + /* Return title. */ + fid = (*env)->GetFieldID(env, optClass, "title", "Ljava/lang/String;"); + str = sopt->title ? (*env)->NewStringUTF(env, sopt->title) : 0; + (*env)->SetObjectField(env, optObj, fid, str); + /* Return descr. */ + fid = (*env)->GetFieldID(env, optClass, "desc", "Ljava/lang/String;"); + (*env)->SetObjectField(env, optObj, fid, + (*env)->NewStringUTF(env, sopt->desc)); + /* Return type. */ + fid = (*env)->GetFieldID(env, optClass, "type", "I"); + (*env)->SetIntField(env, optObj, fid, sopt->type); + /* Return unit. */ + fid = (*env)->GetFieldID(env, optClass, "unit", "I"); + (*env)->SetIntField(env, optObj, fid, sopt->unit); + /* Return size. */ + fid = (*env)->GetFieldID(env, optClass, "size", "I"); + (*env)->SetIntField(env, optObj, fid, sopt->size); + /* Return cap. */ + fid = (*env)->GetFieldID(env, optClass, "cap", "I"); + (*env)->SetIntField(env, optObj, fid, sopt->cap); + /* Return constraint_type. */ + fid = (*env)->GetFieldID(env, optClass, "constraintType", "I"); + (*env)->SetIntField(env, optObj, fid, sopt->constraint_type); + /* + * Now for the constraint itself. + */ + if (sopt->constraint_type == SANE_CONSTRAINT_RANGE) + { + /* Create range object. */ + jclass rangeClass = (*env)->FindClass(env, "SaneRange"); + jobject range = (*env)->AllocObject(env, rangeClass); + /* Fill in fields. */ + fid = (*env)->GetFieldID(env, rangeClass, "min", "I"); + (*env)->SetIntField(env, range, fid, + sopt->constraint.range->min); + fid = (*env)->GetFieldID(env, rangeClass, "max", "I"); + (*env)->SetIntField(env, range, fid, + sopt->constraint.range->max); + fid = (*env)->GetFieldID(env, rangeClass, "quant", "I"); + (*env)->SetIntField(env, range, fid, + sopt->constraint.range->quant); + fid = (*env)->GetFieldID(env, optClass, "rangeConstraint", + "LSaneRange;"); + /* Store range. */ + (*env)->SetObjectField(env, optObj, fid, range); + } + else if (sopt->constraint_type == SANE_CONSTRAINT_WORD_LIST) + { /* Get array of integers. */ + jintArray wordList; + jint *elements; + int i; + /* First word. is the length. */ + wordList = (*env)->NewIntArray(env, + sopt->constraint.word_list[0]); + /* Copy in the integers. */ + elements = (*env)->GetIntArrayElements(env, wordList, 0); + for (i = 0; i < sopt->constraint.word_list[0]; i++) + elements[i] = sopt->constraint.word_list[i]; + (*env)->ReleaseIntArrayElements(env, wordList, elements, 0); + /* Set the field. */ + fid = (*env)->GetFieldID(env, optClass, "wordListConstraint", + "[I"); + (*env)->SetObjectField(env, optObj, fid, wordList); + } + else if (sopt->constraint_type == SANE_CONSTRAINT_STRING_LIST) + { + jclass stringClass = (*env)->FindClass(env, "java/lang/String"); + jobjectArray stringList; + int len; /* Gets # elements */ + int i; + + for (len = 0; sopt->constraint.string_list[len]; len++) + ; + stringList = (*env)->NewObjectArray(env, len + 1, + stringClass, 0); + /* Add each string. */ + for (i = 0; i < len; i++) + { + (*env)->SetObjectArrayElement(env, stringList, i, + (*env)->NewStringUTF(env, + sopt->constraint.string_list[i])); + } + /* 0 at end. */ + (*env)->SetObjectArrayElement(env, stringList, len, 0); + /* Set the field. */ + fid = (*env)->GetFieldID(env, optClass, + "stringListConstraint", "[Ljava/lang/String;"); + (*env)->SetObjectField(env, optObj, fid, stringList); + } + } + +/* + * Class: Sane + * Method: getControlOption + * Signature: (II[I[I)I + */ +JNIEXPORT jint JNICALL Java_Sane_getControlOption__II_3I_3I + (JNIEnv *env, jobject jobj, jint handle, jint option, jintArray value, + jintArray info) + { + SANE_Status status; /* Gets status. */ + SANE_Int i; /* Gets info. passed back. */ + int v; + + status = sane_control_option((SANE_Handle) handle, option, + SANE_ACTION_GET_VALUE, &v, &i); + if (value) + (*env)->SetIntArrayRegion(env, value, 0, 1, &v); + if (info) + (*env)->SetIntArrayRegion(env, info, 0, 1, &i); + return (status); + } + +/* + * Class: Sane + * Method: getControlOption + * Signature: (II[B[I)I + */ +JNIEXPORT jint JNICALL Java_Sane_getControlOption__II_3B_3I + (JNIEnv *env, jobject jobj, jint handle, jint option, jbyteArray value, + jintArray info) + { + SANE_Status status; /* Gets status. */ + SANE_Int i; /* Gets info. passed back. */ + char *str; + + str = (*env)->GetByteArrayElements(env, value, 0); + status = sane_control_option((SANE_Handle) handle, option, + SANE_ACTION_GET_VALUE, str, &i); + (*env)->ReleaseByteArrayElements(env, value, str, 0); + if (info) + (*env)->SetIntArrayRegion(env, info, 0, 1, &i); + return (status); + } + +/* + * Class: Sane + * Method: setControlOption + * Signature: (IIII[I)I + */ +JNIEXPORT jint JNICALL Java_Sane_setControlOption__IIII_3I + (JNIEnv *env, jobject jobj, jint handle, jint option, jint action, + jint value, jintArray info) + { + SANE_Status status; /* Gets status. */ + SANE_Int i; /* Gets info. passed back. */ + status = sane_control_option((SANE_Handle) handle, option, action, + &value, &i); + if (info) + (*env)->SetIntArrayRegion(env, info, 0, 1, &i); + return (status); + } + +/* + * Get string length. This exists because sometimes strings seem to be + * padded with negatives. + */ + +static int String_length + ( + const char *str + ) + { + const char *ptr; + for (ptr = str; *ptr > 0; ptr++) + ; + return ((int) (ptr - str)); + } + +/* + * Class: Sane + * Method: setControlOption + * Signature: (IIILjava/lang/String;[I)I + */ +JNIEXPORT jint JNICALL Java_Sane_setControlOption__IIILjava_lang_String_2_3I + (JNIEnv *env, jobject jobj, jint handle, jint option, jint action, + jstring value, jintArray info) + { + SANE_Status status; /* Gets status. */ + SANE_Int i; /* Gets info. passed back. */ + const char *valuep; + char buf[512]; /* Hope this is big enough. */ + int len; /* Gets string length. */ + + valuep = (*env)->GetStringUTFChars(env, value, 0); + len = String_length(valuep); + if (len >= sizeof(buf)) + len = sizeof(buf) - 1; + strncpy(buf, valuep, len); + buf[len] = 0; /* Insure it's 0-delimited. */ + status = sane_control_option((SANE_Handle) handle, option, action, + (void *) &buf[0], &i); + /* +++++++Want to return new val? */ + (*env)->ReleaseStringUTFChars(env, value, valuep); + if (info) + (*env)->SetIntArrayRegion(env, info, 0, 1, &i); + return (status); + } + +/* + * Class: Sane + * Method: getParameters + * Signature: (ILSaneParameters;)I + */ +JNIEXPORT jint JNICALL Java_Sane_getParameters + (JNIEnv *env, jobject jobj, jint handle, jobject paramsObj) + { + SANE_Status status; /* Gets status. */ + SANE_Parameters params; /* Gets params. */ + jclass paramsClass; /* Gets its class. */ + jfieldID fid; /* Gets each field ID. */ + + status = sane_get_parameters((SANE_Handle) handle, ¶ms); + /* Get class info. */ + paramsClass = (*env)->GetObjectClass(env, paramsObj); + /* Fill in each member. */ + fid = (*env)->GetFieldID(env, paramsClass, "format", "I"); + (*env)->SetIntField(env, paramsObj, fid, params.format); + fid = (*env)->GetFieldID(env, paramsClass, "lastFrame", "Z"); + (*env)->SetBooleanField(env, paramsObj, fid, params.last_frame); + fid = (*env)->GetFieldID(env, paramsClass, "bytesPerLine", "I"); + (*env)->SetIntField(env, paramsObj, fid, params.bytes_per_line); + fid = (*env)->GetFieldID(env, paramsClass, "pixelsPerLine", "I"); + (*env)->SetIntField(env, paramsObj, fid, params.pixels_per_line); + fid = (*env)->GetFieldID(env, paramsClass, "lines", "I"); + (*env)->SetIntField(env, paramsObj, fid, params.lines); + fid = (*env)->GetFieldID(env, paramsClass, "depth", "I"); + (*env)->SetIntField(env, paramsObj, fid, params.depth); + return (status); + } + +/* + * Class: Sane + * Method: start + * Signature: (I)I + */ +JNIEXPORT jint JNICALL Java_Sane_start + (JNIEnv *env, jobject jobj, jint handle) + { + return (sane_start((SANE_Handle) handle)); + } + +/* + * Class: Sane + * Method: read + * Signature: (I[BI[I)I + */ +JNIEXPORT jint JNICALL Java_Sane_read + (JNIEnv *env, jobject jobj, jint handle, jbyteArray data, jint maxLength, + jintArray length) + { + int status; + jbyte *dataElements; + int read_len; /* # bytes read. */ + + /* Get actual data ptr. */ + dataElements = (*env)->GetByteArrayElements(env, data, 0); + /* Do the read. */ + status = sane_read((SANE_Handle) handle, dataElements, + maxLength, &read_len); + (*env)->ReleaseByteArrayElements(env, data, dataElements, 0); + /* Return # bytes read. */ + (*env)->SetIntArrayRegion(env, length, 0, 1, &read_len); + return (status); + } + +/* + * Class: Sane + * Method: cancel + * Signature: (I)V + */ +JNIEXPORT void JNICALL Java_Sane_cancel + (JNIEnv *env, jobject jobj, jint handle) + { + sane_cancel((SANE_Handle) handle); + } + +/* + * Class: Sane + * Method: strstatus + * Signature: (I)Ljava/lang/String; + */ +JNIEXPORT jstring JNICALL Java_Sane_strstatus + (JNIEnv *env, jobject jobj, jint status) + { + const char *str = sane_strstatus(status); + return ((*env)->NewStringUTF(env, str)); + } + +#ifdef __cplusplus +} +#endif diff --git a/japi/Sane.java b/japi/Sane.java new file mode 100644 index 0000000..85600e7 --- /dev/null +++ b/japi/Sane.java @@ -0,0 +1,144 @@ +/* sane - Scanner Access Now Easy. + Copyright (C) 1997 Jeffrey S. Freedman + This file is part of the SANE package. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program 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 + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA. + + As a special exception, the authors of SANE give permission for + additional uses of the libraries contained in this release of SANE. + + The exception is that, if you link a SANE library with other files + to produce an executable, this does not by itself cause the + resulting executable to be covered by the GNU General Public + License. Your use of that executable is in no way restricted on + account of linking the SANE library code into it. + + This exception does not, however, invalidate any other reasons why + the executable file might be covered by the GNU General Public + License. + + If you submit changes to SANE to the maintainers to be included in + a subsequent release, you agree by submitting the changes that + those changes may be distributed with this exception intact. + + If you write modifications of your own for SANE, it is your choice + whether to permit this exception to apply to your modifications. + If you do not wish that, delete this exception notice. */ + +// +// Sane.java - Java version of SANE API. +// +// Written: 10/9/97 - JSF +// + +public class Sane +{ + // + // Public constants: + // +public static int FIXED_SCALE_SHIFT = 16; + // + // Sane status values: + // +public static int STATUS_GOOD = 0; // everything A-OK +public static int STATUS_UNSUPPORTED = 1;// operation is not supported +public static int STATUS_CANCELLED = 2; // operation was cancelled +public static int STATUS_DEVICE_BUSY = 3;// device is busy; try again later +public static int STATUS_INVAL = 4; // data is invalid (includes no + // dev at open) +public static int STATUS_EOF = 5; // no more data available (end-of-file) +public static int STATUS_JAMMED = 6; // document feeder jammed +public static int STATUS_NO_DOCS = 7; // document feeder out of documents +public static int STATUS_COVER_OPEN = 8;// scanner cover is open +public static int STATUS_IO_ERROR = 9; // error during device I/O +public static int STATUS_NO_MEM = 10; // out of memory + // access to resource has been denied +public static int STATUS_ACCESS_DENIED = 11; + // + // Initialize when class is loaded. + // +static { + System.loadLibrary("sanej"); + } + // + // Private methods: + // + // Get list of devices. +private native int getDevicesNative( + SaneDevice[] deviceList, boolean localOnly); + // Get option descriptor. +private native void getOptionNative(int handle, int option, SaneOption opt); + // + // Public methods: + // +public Sane() + { } +public int fix(double v) + { return (int) ((v) * (1 << FIXED_SCALE_SHIFT)); } +public double unfix(int v) + { return (double)(v) / (1 << FIXED_SCALE_SHIFT); } +public int versionMajor(int code) + { return ((code) >> 24) & 0xff; } +public int versionMinor(int code) + { return ((code) >> 16) & 0xff; } +public int versionBuild(int code) + { return ((code) >> 0) & 0xffff; } + // + // SANE interface. + // + // Initialize, and return STATUS_ +public native int init(int[] versionCode); +public native void exit(); // All done. + // Get list of devices. +public int getDevices(SaneDevice[] deviceList, boolean localOnly) + { + // Create objects first. + for (int i = 0; i < deviceList.length - 1; i++) + deviceList[i] = new SaneDevice(); + return getDevicesNative(deviceList, localOnly); + } + // Open a device. +public native int open(String deviceName, int[] handle); + // Close a device. +public native void close(int handle); + // Get option descriptor. +public SaneOption getOptionDescriptor(int handle, int option) + { + SaneOption opt = new SaneOption(); + opt.name = null; + getOptionNative(handle, option, opt); + if (opt.name == null) // Error? + return (null); + return (opt); + } + // Get each type of option: +public native int getControlOption(int handle, int option, int [] value, + int [] info); +public native int getControlOption(int handle, int option, byte [] value, + int [] info); + // Set each type of option (SET_VALUE or + // SET_AUTO): +public native int setControlOption(int handle, int option, + int action, int value, int [] info); +public native int setControlOption(int handle, int option, + int action, String value, int [] info); +public native int getParameters(int handle, SaneParameters params); +public native int start(int handle); +public native int read(int handle, byte [] data, + int maxLength, int [] length); +public native void cancel(int handle); +public native String strstatus(int status); +} diff --git a/japi/SaneDevice.java b/japi/SaneDevice.java new file mode 100644 index 0000000..dc73365 --- /dev/null +++ b/japi/SaneDevice.java @@ -0,0 +1,55 @@ +/* sane - Scanner Access Now Easy. + Copyright (C) 1997 Jeffrey S. Freedman + This file is part of the SANE package. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program 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 + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA. + + As a special exception, the authors of SANE give permission for + additional uses of the libraries contained in this release of SANE. + + The exception is that, if you link a SANE library with other files + to produce an executable, this does not by itself cause the + resulting executable to be covered by the GNU General Public + License. Your use of that executable is in no way restricted on + account of linking the SANE library code into it. + + This exception does not, however, invalidate any other reasons why + the executable file might be covered by the GNU General Public + License. + + If you submit changes to SANE to the maintainers to be included in + a subsequent release, you agree by submitting the changes that + those changes may be distributed with this exception intact. + + If you write modifications of your own for SANE, it is your choice + whether to permit this exception to apply to your modifications. + If you do not wish that, delete this exception notice. */ + +// +// SaneDevice.java - Device Descriptor. +// +// Written: 10/9/97 - JSF +// + +public class SaneDevice +{ +public String name; // unique device name +public String vendor; // device vendor string +public String model; // device model name +public String type; // device type (e.g., "flatbed scanner") +} + + diff --git a/japi/SaneOption.java b/japi/SaneOption.java new file mode 100644 index 0000000..ed460c7 --- /dev/null +++ b/japi/SaneOption.java @@ -0,0 +1,145 @@ +/* sane - Scanner Access Now Easy. + Copyright (C) 1997 Jeffrey S. Freedman + This file is part of the SANE package. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program 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 + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA. + + As a special exception, the authors of SANE give permission for + additional uses of the libraries contained in this release of SANE. + + The exception is that, if you link a SANE library with other files + to produce an executable, this does not by itself cause the + resulting executable to be covered by the GNU General Public + License. Your use of that executable is in no way restricted on + account of linking the SANE library code into it. + + This exception does not, however, invalidate any other reasons why + the executable file might be covered by the GNU General Public + License. + + If you submit changes to SANE to the maintainers to be included in + a subsequent release, you agree by submitting the changes that + those changes may be distributed with this exception intact. + + If you write modifications of your own for SANE, it is your choice + whether to permit this exception to apply to your modifications. + If you do not wish that, delete this exception notice. */ + +// +// SaneOption.java - Sane option descriptor. +// +// Written: 10/9/97 - JSF +// + +public class SaneOption + { + // + // Sane option types: + // + public static final int TYPE_BOOL = 0; + public static final int TYPE_INT = 1; + public static final int TYPE_FIXED = 2; + public static final int TYPE_STRING = 3; + public static final int TYPE_BUTTON = 4; + public static final int TYPE_GROUP = 5; + // + // Sane value units: + // + public static final int UNIT_NONE = 0; // the value is unit-less + // (e.g., # of scans) + public static final int UNIT_PIXEL = 1; // value is number of pixels + public static final int UNIT_BIT = 2; // value is number of bits + public static final int UNIT_MM = 3; // value is millimeters + public static final int UNIT_DPI = 4; // value is res. in dots/inch + public static final int UNIT_PERCENT = 5;// value is a percentage + // + // Option capabilities: + // + public static final int CAP_SOFT_SELECT = (1 << 0); + public static final int CAP_HARD_SELECT = (1 << 1); + public static final int CAP_SOFT_DETECT = (1 << 2); + public static final int CAP_EMULATED = (1 << 3); + public static final int CAP_AUTOMATIC = (1 << 4); + public static final int CAP_INACTIVE = (1 << 5); + public static final int CAP_ADVANCED = (1 << 6); + // + // Constraints: + // + public static final int CONSTRAINT_NONE = 0; + public static final int CONSTRAINT_RANGE = 1; + public static final int CONSTRAINT_WORD_LIST = 2; + public static final int CONSTRAINT_STRING_LIST = 3; + // + // Actions for controlOption(): + // + public static final int ACTION_GET_VALUE = 0; + public static final int ACTION_SET_VALUE = 1; + public static final int ACTION_SET_AUTO = 2; + + // + // Flags passed back in 'info' field param. of + // setControlOption(): + // + public static final int INFO_INEXACT = (1 << 0); + public static final int INFO_RELOAD_OPTIONS = (1 << 1); + public static final int INFO_RELOAD_PARAMS = (1 << 2); + + // + // Class members: + // + public String name; // name of this option (command-line name) + public String title; // title of this option (single-line) + public String desc; // description of this option (multi-line) + public int type; // how are values interpreted? (TYPE_) + public int unit; // what is the (physical) unit? (UNIT_) + public int size; + public int cap; // capabilities + public int constraintType; + // These are a union in the "C" API: + // Null-terminated list: + public String[] stringListConstraint; + // First element is list-length: + public int[] wordListConstraint; + public SaneRange rangeConstraint; + // + // Public methods: + // + public boolean is_active() + { return ((cap) & CAP_INACTIVE) == 0; } + public boolean is_settable() + { return ((cap) & CAP_SOFT_SELECT) == 0; } + // Return string describing units. + // "unitLength" is # mm. preferred. + public String unitString(double unitLength) + { + switch (unit) + { + case UNIT_NONE: return "none"; + case UNIT_PIXEL: return "pixel"; + case UNIT_BIT: return "bit"; + case UNIT_DPI: return "dpi"; + case UNIT_PERCENT: return "%"; + case UNIT_MM: + if (unitLength > 9.9 && unitLength < 10.1) + return "cm"; + else if (unitLength > 25.3 && unitLength < 25.5) + return "in"; + return "mm"; + } + return ""; + } + } + diff --git a/japi/SaneParameters.java b/japi/SaneParameters.java new file mode 100644 index 0000000..4e629c4 --- /dev/null +++ b/japi/SaneParameters.java @@ -0,0 +1,68 @@ +/* sane - Scanner Access Now Easy. + Copyright (C) 1997 Jeffrey S. Freedman + This file is part of the SANE package. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program 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 + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA. + + As a special exception, the authors of SANE give permission for + additional uses of the libraries contained in this release of SANE. + + The exception is that, if you link a SANE library with other files + to produce an executable, this does not by itself cause the + resulting executable to be covered by the GNU General Public + License. Your use of that executable is in no way restricted on + account of linking the SANE library code into it. + + This exception does not, however, invalidate any other reasons why + the executable file might be covered by the GNU General Public + License. + + If you submit changes to SANE to the maintainers to be included in + a subsequent release, you agree by submitting the changes that + those changes may be distributed with this exception intact. + + If you write modifications of your own for SANE, it is your choice + whether to permit this exception to apply to your modifications. + If you do not wish that, delete this exception notice. */ + +// +// SaneParameters.java - Sane parameters. +// +// Written: 10/14/97 - JSF +// + +public class SaneParameters +{ + // + // Frame values: + // +public static final int FRAME_GRAY = 0; // band covering human visual range +public static final int FRAME_RGB = 1; // pixel-interleaved + // red/green/blue bands +public static final int FRAME_RED = 2; // red band only +public static final int FRAME_GREEN = 3;// green band only +public static final int FRAME_BLUE = 4; // blue band only + + // + // Class members: + // +public int format; +public boolean lastFrame; +public int bytesPerLine; +public int pixelsPerLine; +public int lines; +public int depth; +} diff --git a/japi/SaneRange.java b/japi/SaneRange.java new file mode 100644 index 0000000..4790e32 --- /dev/null +++ b/japi/SaneRange.java @@ -0,0 +1,53 @@ +/* sane - Scanner Access Now Easy. + Copyright (C) 1997 Jeffrey S. Freedman + This file is part of the SANE package. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program 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 + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA. + + As a special exception, the authors of SANE give permission for + additional uses of the libraries contained in this release of SANE. + + The exception is that, if you link a SANE library with other files + to produce an executable, this does not by itself cause the + resulting executable to be covered by the GNU General Public + License. Your use of that executable is in no way restricted on + account of linking the SANE library code into it. + + This exception does not, however, invalidate any other reasons why + the executable file might be covered by the GNU General Public + License. + + If you submit changes to SANE to the maintainers to be included in + a subsequent release, you agree by submitting the changes that + those changes may be distributed with this exception intact. + + If you write modifications of your own for SANE, it is your choice + whether to permit this exception to apply to your modifications. + If you do not wish that, delete this exception notice. */ + +// +// SaneRange.java - Sane range info. +// +// Written: 10/9/97 - JSF +// + +public class SaneRange +{ +public int min; // minimum (element) value +public int max; // maximum (element) value +public int quant; // Quantization value (0 if none) +} + diff --git a/japi/ScanIt.java b/japi/ScanIt.java new file mode 100644 index 0000000..21afba0 --- /dev/null +++ b/japi/ScanIt.java @@ -0,0 +1,391 @@ +/* sane - Scanner Access Now Easy. + Copyright (C) 1997 Jeffrey S. Freedman + This file is part of the SANE package. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program 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 + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA. + + As a special exception, the authors of SANE give permission for + additional uses of the libraries contained in this release of SANE. + + The exception is that, if you link a SANE library with other files + to produce an executable, this does not by itself cause the + resulting executable to be covered by the GNU General Public + License. Your use of that executable is in no way restricted on + account of linking the SANE library code into it. + + This exception does not, however, invalidate any other reasons why + the executable file might be covered by the GNU General Public + License. + + If you submit changes to SANE to the maintainers to be included in + a subsequent release, you agree by submitting the changes that + those changes may be distributed with this exception intact. + + If you write modifications of your own for SANE, it is your choice + whether to permit this exception to apply to your modifications. + If you do not wish that, delete this exception notice. */ + +/** + ** ScanIt.java - Do the actual scanning for SANE. + ** + ** Written: 11/3/97 - JSF + **/ + +import java.util.Vector; +import java.util.Enumeration; +import java.awt.image.ImageProducer; +import java.awt.image.ImageConsumer; +import java.awt.image.ColorModel; +import java.io.OutputStream; +import java.io.PrintWriter; +import java.io.BufferedWriter; +import java.io.IOException; + +/* + * This class uses SANE to scan an image. + */ +public class ScanIt implements ImageProducer + { + // # lines we incr. image height. + private static final int STRIP_HEIGHT = 256; + private Sane sane; + private int handle = 0; // SANE device handle. + private Vector consumers = new Vector(); + // File to write to. + private OutputStream outputFile = null; + private SaneParameters parms = new SaneParameters(); + private ColorModel cm; // RGB color model. + private int width, height; // Dimensions. + private int x, y; // Position. + private int image[] = null; // Image that we build as we scan. + private int offset; // Offset within image in pixels if + // doing separate frames, bytes + // (3/word) if RBG. + + /* + * Tell consumers our status. The scan is also terminated de- + * pending on the status. + */ + private void tellStatus(int s) + { + Enumeration next = consumers.elements(); + while (next.hasMoreElements()) + { + ImageConsumer ic = (ImageConsumer) next.nextElement(); + ic.imageComplete(s); + } + // Done? Stop scan. + if (s == ImageConsumer.STATICIMAGEDONE || + s == ImageConsumer.IMAGEERROR) + sane.cancel(handle); + } + + /* + * Tell consumers the image size. + */ + private void tellDimensions(int w, int h) + { + System.out.println("tellDimensions: " + w + ", " + h); + Enumeration next = consumers.elements(); + while (next.hasMoreElements()) + { + ImageConsumer ic = (ImageConsumer) next.nextElement(); + ic.setDimensions(w, h); + } + } + + /* + * Send pixels to the clients. + */ + private void tellPixels(int x, int y, int w, int h) + { +/* + System.out.println("image length=" + image.length); + System.out.println("width=" + width); + System.out.println("tellPixels: x="+x +" y="+y + " w="+w + + " h="+h); + */ + Enumeration next = consumers.elements(); + while (next.hasMoreElements()) + { + ImageConsumer ic = (ImageConsumer) next.nextElement(); + ic.setPixels(x, y, w, h, cm, image, 0, width); + } + } + + /* + * Construct. + */ + public ScanIt(Sane s, int hndl) + { + sane = s; + handle = hndl; + } + + /* + * Add a consumer. + */ + public synchronized void addConsumer(ImageConsumer ic) + { + if (consumers.contains(ic)) + return; // Already here. + consumers.addElement(ic); + } + + /* + * Is a consumer in the list? + */ + public synchronized boolean isConsumer(ImageConsumer ic) + { return consumers.contains(ic); } + + /* + * Remove consumer. + */ + public synchronized void removeConsumer(ImageConsumer ic) + { consumers.removeElement(ic); } + + /* + * Add a consumer and start scanning. + */ + public void startProduction(ImageConsumer ic) + { + System.out.println("In startProduction()"); + addConsumer(ic); + scan(); + } + + /* + * Set file to write to. + */ + public void setOutputFile(OutputStream o) + { outputFile = o; } + + /* + * Ignore this: + */ + public void requestTopDownLeftRightResend(ImageConsumer ic) + { } + + /* + * Go to next line in image, reallocating if necessary. + */ + private void nextLine() + { + x = 0; + ++y; + if (y >= height || image == null) + { // Got to reallocate. + int oldSize = image == null ? 0 : width*height; + height += STRIP_HEIGHT; // Add more lines. + int newSize = width*height; + int[] newImage = new int[newSize]; + int i; + if (oldSize != 0) // Copy old data. + for (i = 0; i < oldSize; i++) + newImage[i] = image[i]; + // Fill new pixels with 0's, setting + // alpha channel. + for (i = oldSize; i < newSize; i++) + newImage[i] = (255 << 24); + image = newImage; + System.out.println("nextLine: newSize="+newSize); + // Tell clients. + tellDimensions(width, height); + } + } + + /* + * Process a buffer of data. + */ + private boolean process(byte[] data, int readLen) + { + int prevY = y > 0 ? y : 0; // Save current Y-coord. + int i; + switch (parms.format) + { + case SaneParameters.FRAME_RED: + case SaneParameters.FRAME_GREEN: + case SaneParameters.FRAME_BLUE: + System.out.println("Process RED, GREEN or BLUE"); + int cindex = 2 - (parms.format - SaneParameters.FRAME_RED); + // Single frame. + for (i = 0; i < readLen; ++i) + { // Doing a single color frame. + image[offset + i] |= + (((int) data[i]) & 0xff) << (8*cindex); + ++x; + if (x >= width) + nextLine(); + } + break; + case SaneParameters.FRAME_RGB: + for (i = 0; i < readLen; ++i) + { + int b = 2 - (offset + i)%3; + image[(offset + i)/3] |= + (((int) data[i]) & 0xff) << (8*b); + if (b == 0) + { + ++x; + if (x >= width) + nextLine(); + } + } + break; + case SaneParameters.FRAME_GRAY: + System.out.println("Process GREY"); + // Single frame. + for (i = 0; i < readLen; ++i) + { + int v = ((int) data[i]) & 0xff; + image[offset + i] |= (v<<16) | (v<<8) | (v); + ++x; + if (x >= width) + nextLine(); + } + break; + } + offset += readLen; // Update where we are. + // Show it. + System.out.println("PrevY = " + prevY + ", y = " + y); +// tellPixels(0, prevY, width, y - prevY); + tellPixels(0, 0, width, height); + return true; + } + + /* + * Start scanning. + */ + public void scan() + { + int dataLen = 32*1024; + byte [] data = new byte[dataLen]; + int [] readLen = new int[1]; + int frameCnt = 0; + // For now, use default RGB model. + cm = ColorModel.getRGBdefault(); + int status; + image = null; + do // Do each frame. + { + frameCnt++; + x = 0; // Init. position. + y = -1; + offset = 0; + System.out.println("Reading frame #" + frameCnt); + status = sane.start(handle); + if (status != Sane.STATUS_GOOD) + { + System.out.println("start() failed. Status= " + + status); + tellStatus(ImageConsumer.IMAGEERROR); + return; + } + status = sane.getParameters(handle, parms); + if (status != Sane.STATUS_GOOD) + { + System.out.println("getParameters() failed. Status= " + + status); + tellStatus(ImageConsumer.IMAGEERROR); + return; //++++cleanup. + } + if (frameCnt == 1) // First time? + { + width = parms.pixelsPerLine; + if (parms.lines >= 0) + height = parms.lines - STRIP_HEIGHT + 1; + else // Hand-scanner. + height = 0; + nextLine(); // Allocate image. + } + while ((status = sane.read(handle, data, dataLen, readLen)) + == Sane.STATUS_GOOD) + { + System.out.println("Read " + readLen[0] + " bytes."); + if (!process(data, readLen[0])) + { + tellStatus(ImageConsumer.IMAGEERROR); + return; + } + } + if (status != Sane.STATUS_EOF) + { + System.out.println("read() failed. Status= " + + status); + tellStatus(ImageConsumer.IMAGEERROR); + return; + } + } + while (!parms.lastFrame); + height = y; // For now, send whole image here. + tellDimensions(width, height); + tellPixels(0, 0, width, height); + if (outputFile != null) // Write to file. + { + try + { + write(outputFile); + } + catch (IOException e) + { //+++++++++++++++ + System.out.println("I/O error writing file."); + } + outputFile = null; // Clear for next time. + } + tellStatus(ImageConsumer.STATICIMAGEDONE); + image = null; // Allow buffer to be freed. + } + + /* + * Write ppm/pnm output for last scan to a file. + */ + private void write(OutputStream out) throws IOException + { + PrintWriter pout = new PrintWriter(out); + BufferedWriter bout = new BufferedWriter(pout); + int len = width*height; // Get # of pixels. + int i; + switch (parms.format) + { + case SaneParameters.FRAME_RED: + case SaneParameters.FRAME_GREEN: + case SaneParameters.FRAME_BLUE: + case SaneParameters.FRAME_RGB: + pout.print("P6\n# SANE data follows\n" + + width + ' ' + height + "\n255\n"); + for (i = 0; i < len; i++) + { + int pix = image[i]; + bout.write((pix >> 16) & 0xff); + bout.write((pix >> 8) & 0xff); + bout.write(pix & 0xff); + } + break; + case SaneParameters.FRAME_GRAY: + pout.print("P5\n# SANE data follows\n" + + width + ' ' + height + "\n255\n"); + for (i = 0; i < len; i++) + { + int pix = image[i]; + bout.write(pix & 0xff); + } + break; + } + + bout.flush(); // Flush output. + pout.flush(); + } + } diff --git a/japi/Test.java b/japi/Test.java new file mode 100644 index 0000000..52a7112 --- /dev/null +++ b/japi/Test.java @@ -0,0 +1,175 @@ +/* sane - Scanner Access Now Easy. + Copyright (C) 1997 Jeffrey S. Freedman + This file is part of the SANE package. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program 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 + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA. + + As a special exception, the authors of SANE give permission for + additional uses of the libraries contained in this release of SANE. + + The exception is that, if you link a SANE library with other files + to produce an executable, this does not by itself cause the + resulting executable to be covered by the GNU General Public + License. Your use of that executable is in no way restricted on + account of linking the SANE library code into it. + + This exception does not, however, invalidate any other reasons why + the executable file might be covered by the GNU General Public + License. + + If you submit changes to SANE to the maintainers to be included in + a subsequent release, you agree by submitting the changes that + those changes may be distributed with this exception intact. + + If you write modifications of your own for SANE, it is your choice + whether to permit this exception to apply to your modifications. + If you do not wish that, delete this exception notice. */ + +class Test +{ +public static void main(String[] args) + { + Sane sane = new Sane(); + int version[] = new int[1]; // Array to get version #. + int status = sane.init(version); + if (status != Sane.STATUS_GOOD) + { + System.out.println("getDevices() failed. Status= " + status); + return; + } + System.out.println("VersionMajor =" + sane.versionMajor(version[0])); + System.out.println("VersionMinor =" + sane.versionMinor(version[0])); + System.out.println("VersionBuild =" + sane.versionBuild(version[0])); + // Get list of devices. + // Allocate room for 50. + SaneDevice devList[] = new SaneDevice[50]; + status = sane.getDevices(devList, false); + if (status != Sane.STATUS_GOOD) + { + System.out.println("getDevices() failed. Status= " + status); + return; + } + for (int i = 0; i < 50 && devList[i] != null; i++) + { + System.out.println("Device '" + devList[i].name + "' is a " + + devList[i].vendor + " " + devList[i].model + " " + + devList[i].type); + } + int handle[] = new int[1]; + status = sane.open(devList[0].name, handle); + if (status != Sane.STATUS_GOOD) + { + System.out.println("open() failed. Status= " + status); + return; + } + System.out.println("Open handle=" + handle[0]); + // Get # of device options. + int numDevOptions[] = new int[1]; + status = sane.getControlOption(handle[0], 0, numDevOptions, null); + if (status != Sane.STATUS_GOOD) + { + System.out.println("controlOption() failed. Status= " + + status); + return; + } + System.out.println("Number of device options=" + numDevOptions[0]); + for (int i = 0; i < numDevOptions[0]; i++) + { + SaneOption opt = sane.getOptionDescriptor(handle[0], i); + if (opt == null) + { + System.out.println("getOptionDescriptor() failed for " + + i); + continue; + } + System.out.println("Option name: " + opt.name); + System.out.println("Option title: " + opt.title); + System.out.println("Option desc: " + opt.desc); + switch (opt.constraintType) + { + case SaneOption.CONSTRAINT_RANGE: + System.out.println("Range: " + + opt.rangeConstraint.min + ", " + + opt.rangeConstraint.max + ", " + + opt.rangeConstraint.quant); + break; + case SaneOption.CONSTRAINT_WORD_LIST: + System.out.print("Word list: "); + for (int j = 0; j < opt.wordListConstraint[0]; j++) + System.out.print(opt.wordListConstraint[j]); + System.out.println(); + break; + case SaneOption.CONSTRAINT_STRING_LIST: + for (int j = 0; opt.stringListConstraint[j] != null; + j++) + System.out.print("String constraint: " + + opt.stringListConstraint[j]); + break; + default: + System.out.println("No constraint."); + break; + } + } + status = sane.setControlOption(handle[0], 2, + SaneOption.ACTION_SET_VALUE, "../test1.pnm", null); + if (status != Sane.STATUS_GOOD) + { + System.out.println("setControlOption() failed. Status= " + + status); + } + // + // Main scanning loop. + // + SaneParameters parm = new SaneParameters(); + int dataLen = 32*1024; + byte [] data = new byte[dataLen]; + int [] readLen = new int[1]; + int frameCnt = 0; + do + { + frameCnt++; + System.out.println("Reading frame #" + frameCnt); + status = sane.start(handle[0]); + if (status != Sane.STATUS_GOOD) + { + System.out.println("start() failed. Status= " + + status); + return; + } + status = sane.getParameters(handle[0], parm); + if (status != Sane.STATUS_GOOD) + { + System.out.println("getParameters() failed. Status= " + + status); + return; //++++cleanup. + } + while ((status = sane.read(handle[0], data, dataLen, readLen)) + == Sane.STATUS_GOOD) + { + System.out.println("Read " + readLen[0] + " bytes."); + // ++++++++Process data. + } + if (status != Sane.STATUS_EOF) + { + System.out.println("read() failed. Status= " + + status); + } + } + while (!parm.lastFrame); + + sane.close(handle[0]); + } +} -- cgit v1.2.3