kopia lustrzana https://gitlab.com/sane-project/backends
				
				
				
			
		
			
				
	
	
		
			494 wiersze
		
	
	
		
			15 KiB
		
	
	
	
		
			C
		
	
	
			
		
		
	
	
			494 wiersze
		
	
	
		
			15 KiB
		
	
	
	
		
			C
		
	
	
| /* 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
 |