1
1
/*-------------------------------------------------------------------------
2
2
| rxtx is a native interface to serial ports in java.
3
| Copyright 1997-2002 by Trent Jarvi taj@www.linux.org.uk
3
| Copyright 1997-2004 by Trent Jarvi taj@www.linux.org.uk
5
5
| This library is free software; you can redistribute it and/or
6
6
| modify it under the terms of the GNU Library General Public
131
138
return(JNI_TRUE);
143
#define CTL_CODE( DeviceType, Function, Method, Access ) (((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method))
145
#define FILE_DEVICE_PARALLEL_PORT 0x00000016
146
#define METHOD_BUFFERED 0
147
#define FILE_ANY_ACCESS 0
149
#define IOCTL_PAR_QUERY_INFORMATION CTL_CODE(FILE_DEVICE_PARALLEL_PORT,1,METHOD_BUFFERED,FILE_ANY_ACCESS)
151
#define PARALLEL_INIT 0x1
152
#define PARALLEL_AUTOFEED 0x2
153
#define PARALLEL_PAPER_EMPTY 0x4
154
#define PARALLEL_OFF_LINE 0x8
155
#define PARALLEL_POWER_OFF 0x10
156
#define PARALLEL_NOT_CONNECTED 0x20
157
#define PARALLEL_BUSY 0x40
158
#define PARALLEL_SELECTED 0x80
160
int getWin32ParallelStatusFlags(int fd){
163
if(!DeviceIoControl( (HANDLE)fd, IOCTL_PAR_QUERY_INFORMATION, NULL,0, &status, sizeof(status), &count, 0) && count == 1){
168
printf("getWin32ParallelStatusFlags: %d\n", status );
173
jboolean getWin32ParallelStatus(int fd, int flag){
174
return( (getWin32ParallelStatusFlags(fd) & flag) ? JNI_TRUE : JNI_FALSE);
133
178
/*----------------------------------------------------------
134
179
LPRPort.isPaperOut
146
190
int fd = get_java_var( env, jobj,"fd","I" );
147
191
#if defined (__linux__)
148
193
ioctl(fd, LPGETSTATUS,&status);
149
194
return( status & LP_NOPA ? JNI_TRUE : JNI_FALSE );
195
#elif defined (WIN32)
196
return getWin32ParallelStatus( fd, PARALLEL_PAPER_EMPTY);
152
199
printf("ParallelImp.c LPGETSTATUS not defined\n");
164
211
JNIEXPORT jboolean JNICALL LPRPort(isPrinterBusy)(JNIEnv *env,
214
int fd = get_java_var( env, jobj,"fd","I" );
168
int fd = get_java_var( env, jobj,"fd","I" );
169
216
#if defined (__linux__)
170
217
ioctl(fd, LPGETSTATUS, &status);
218
#elif defined (WIN32)
219
return getWin32ParallelStatus( fd, PARALLEL_BUSY);
173
222
printf("ParallelImp.c LPGETSTATUS not defined\n");
191
240
JNIEXPORT jboolean JNICALL LPRPort(isPrinterError)(JNIEnv *env,
195
243
int fd = get_java_var( env, jobj,"fd","I" );
196
244
#if defined (__linux__)
197
246
ioctl(fd, LPGETSTATUS, &status);
198
247
return( status & LP_ERR ? JNI_TRUE : JNI_FALSE );
248
#elif defined (WIN32)
249
return getWin32ParallelStatus( fd, PARALLEL_PAPER_EMPTY |
252
PARALLEL_NOT_CONNECTED |
201
256
printf("ParallelImp.c LPGETSTATUS not defined\n");
213
268
JNIEXPORT jboolean JNICALL LPRPort(isPrinterSelected)(JNIEnv *env,
217
271
int fd = get_java_var( env, jobj,"fd","I" );
218
272
#if defined (__linux__)
219
274
ioctl(fd, LPGETSTATUS, &status);
220
275
return( status & LP_SELEC ? JNI_TRUE : JNI_FALSE );
276
#elif defined (WIN32)
277
return getWin32ParallelStatus( fd, PARALLEL_SELECTED);
223
280
printf("ParallelImp.c LPGETSTATUS not defined\n");
237
294
JNIEXPORT jboolean JNICALL LPRPort(isPrinterTimedOut)(JNIEnv *env,
297
#if defined(__linux__)
298
int fd = get_java_var( env, jobj,"fd","I" );
241
int fd = get_java_var( env, jobj,"fd","I" );
242
#if defined(__linux__)
243
300
ioctl(fd, LPGETSTATUS, &status);
244
301
return( status & LP_BUSY ? JNI_TRUE : JNI_FALSE );
268
325
for SIGIO, and installs SIG_IGN if there is not. This is necessary
269
326
for the native threads jdk, but we don't want to do it with green
270
327
threads, because it slows things down. Go figure. */
271
329
struct sigaction handler;
272
330
sigaction( SIGIO, NULL, &handler );
273
331
if( !handler.sa_handler ) signal( SIGIO, SIG_IGN );
292
351
/*struct termios ttyset;*/
293
352
const char *filename = (*env)->GetStringUTFChars( env, jstr, 0 );
354
int fd = (int)CreateFile( filename, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0 );
294
356
int fd = open( filename, O_RDWR | O_NONBLOCK );
295
358
(*env)->ReleaseStringUTFChars( env, jstr, NULL );
296
359
if( fd < 0 ) goto fail;
300
throw_java_exception( env, PORT_IN_USE_EXCEPTION, "open",
363
throw_java_exception_system_msg( env, PORT_IN_USE_EXCEPTION, "open" );
334
400
unsigned char byte = (unsigned char)ji;
335
401
int fd = get_java_var( env, jobj,"fd","I" );
404
DWORD countWritten; /* Fixme, should be a loop until all is written */
405
if( WriteFile( (HANDLE)fd, &byte, sizeof( unsigned char ), &countWritten, NULL ) < 0 ) return;
337
407
if( write( fd, &byte, sizeof( unsigned char ) ) >= 0 ) return;
338
throw_java_exception( env, IO_EXCEPTION, "writeByte",
409
throw_java_exception_system_msg( env, IO_EXCEPTION, "writeByte" );
353
423
JNIEXPORT void JNICALL LPRPort(writeArray)( JNIEnv *env,
354
424
jobject jobj, jbyteArray jbarray, jint offset, jint count )
427
DWORD countWritten; /* Fixme, should be a loop until all is written */
428
COMMTIMEOUTS timeouts;
356
431
int fd = get_java_var( env, jobj,"fd","I" );
357
432
jbyte *body = (*env)->GetByteArrayElements( env, jbarray, 0 );
358
433
unsigned char *bytes = (unsigned char *)malloc( count );
360
435
for( i = 0; i < count; i++ ) bytes[ i ] = body[ i + offset ];
361
436
(*env)->ReleaseByteArrayElements( env, jbarray, body, 0 );
439
we set a timeout because all calls are sequentiell (also with asynchron)
440
this means that the default timeout of unlimited
441
blocks all calls (also close and status request) if the device is down
443
GetCommTimeouts( (HANDLE)fd, &timeouts );
444
timeouts.WriteTotalTimeoutMultiplier = 0;
445
timeouts.WriteTotalTimeoutConstant = 2000; /* 2000 is the min value for the default Windows NT and Windows 2000 driver */
446
SetCommTimeouts( (HANDLE)fd, &timeouts );
448
if(!WriteFile( (HANDLE)fd, bytes, count, &countWritten, NULL ) && countWritten == 0){
450
this are 20 * 2 seconds, in this time a printer (or other parallel device)
451
should solv all problems like buffer full, etc
453
if(errorCount++ < 20){
454
Sleep( 20 ); /* make a small pause to execute all other requests in all other threads */
457
throw_java_exception_system_msg( env, IO_EXCEPTION, "writeArray" );
461
bytes += countWritten;
462
count -= countWritten;
362
465
if( write( fd, bytes, count ) < 0 )
363
throw_java_exception( env, IO_EXCEPTION, "writeArray",
466
throw_java_exception_system_msg( env, IO_EXCEPTION, "writeArray" );
409
512
if( ret == 0 ) break;
410
513
if( ret < 0 ) return -1;
516
if(!ReadFile( (HANDLE)fd, buffer + bytes, left, (DWORD *)&ret, NULL )){
412
521
ret = read( fd, buffer + bytes, left );
413
523
if( ret == 0 ) break;
414
524
if( ret < 0 ) return -1;
439
549
bytes = read_byte_array( fd, buffer, 1, 1, timeout );
442
throw_java_exception( env, IO_EXCEPTION, "readByte",
552
throw_java_exception_system_msg( env, IO_EXCEPTION, "readByte" );
468
577
threshold = get_java_var( env, jobj,"threshold","I" );
469
578
timeout = get_java_var( env, jobj,"threshold","I" );
471
if( length < 1 || length > SSIZE_MAX )
580
if( (size_t) length < 1 || (size_t) length > SSIZE_MAX )
473
582
throw_java_exception( env, IO_EXCEPTION, "readArray",
474
583
"Invalid length" );
478
587
buffer = (unsigned char *)malloc( sizeof( unsigned char ) * length );
479
588
if( buffer == 0 )
481
throw_java_exception( env, IO_EXCEPTION, "writeByte",
590
throw_java_exception( env, IO_EXCEPTION, "readArray",
482
591
"Unable to allocate buffer" );
491
throw_java_exception( env, IO_EXCEPTION, "readArray",
600
throw_java_exception_system_msg( env, IO_EXCEPTION, "readArray" );
555
663
report("LPRPort:nativeavailable: ioctl() failed\n");
556
664
LEAVE( "LPRPort:nativeavailable" );
558
throw_java_exception( env, IO_EXCEPTION, "nativeavailable",
666
throw_java_exception_system_msg( env, IO_EXCEPTION, "nativeavailable" );
560
667
return (jint)result;
749
#if defined(PARALLEL_BUSY)
750
if (pflags & PARALLEL_BUSY)
751
send_event( env, jobj, PAR_EV_ERROR, JNI_TRUE );
752
#elif defined(LP_BUSY)
641
753
if (pflags&LP_BUSY) /* inverted input, active high */
642
754
send_event( env, jobj, PAR_EV_ERROR, JNI_TRUE );
643
755
#elif defined(EBUSY)
649
761
if (pflags&LP_ACK)
650
762
send_event( env, jobj, PAR_EV_ERROR, JNI_TRUE );
652
766
#if defined (__linux__)
653
767
/* unchanged input, active low */
654
768
if (pflags&LP_NOPA) /* unchanged input, active high */
710
825
----------------------------------------------------------*/
711
826
void throw_java_exception( JNIEnv *env, char *exc, char *foo, char *msg )
714
830
jclass clazz = (*env)->FindClass( env, exc );
718
834
(*env)->ExceptionClear( env );
837
/* reduce the message size if it to large for the message buffer */
838
if(MSG_SIZE < (strlen( msg ) + strlen(foo) + 5)){
839
msg[ MSG_SIZE - strlen(foo) - 5] = 0;
721
841
#if defined(_GNU_SOURCE)
722
842
snprintf( buf, 60, "%s in %s", msg, foo );
728
848
(*env)->DeleteLocalRef( env, clazz );
851
void throw_java_exception_system_msg( JNIEnv *env, char *exc, char *foo )
856
FORMAT_MESSAGE_ALLOCATE_BUFFER |
857
FORMAT_MESSAGE_FROM_SYSTEM,
860
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
861
(LPSTR)&allocTextBuf,
864
throw_java_exception( env, exc, foo, allocTextBuf );
865
LocalFree(allocTextBuf);
867
throw_java_exception( env, exc, foo, strerror( errno ) );
870
/*----------------------------------------------------------
873
accept: string to send to report as an error
874
perform: send the string to stderr or however it needs to be reported.
878
----------------------------------------------------------*/
879
void report_error(char *msg)
882
fprintf(stderr, msg);
884
mexWarnMsgTxt( msg );
885
#endif /* DEBUG_MW */
731
888
/*----------------------------------------------------------