diff options
Diffstat (limited to 'japi/Sane.c')
-rw-r--r-- | japi/Sane.c | 493 |
1 files changed, 493 insertions, 0 deletions
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 <sane/sane.h> +#include <string.h> + +#include <stdio.h> /* 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 |