~ubuntu-branches/ubuntu/edgy/rxtx/edgy-201105201527

« back to all changes in this revision

Viewing changes to src/ParallelImp.c

  • Committer: Bazaar Package Importer
  • Author(s): Mario Joussen
  • Date: 2006-03-01 18:56:52 UTC
  • mfrom: (1.1.2 upstream) (2.1.1 etch)
  • Revision ID: james.westby@ubuntu.com-20060301185652-ri9941gi01goklvz
Tags: 2.1.7-2
Fixed stupid bug in clean target.
(closes: Bug#354859)

Show diffs side-by-side

added added

removed removed

Lines of Context:
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
4
4
|
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
31
31
#if defined(__MWERKS__)/* dima */
32
32
#include "LPRPort.h"
33
33
#else /* dima */
34
 
#include "config.h"
 
34
#ifndef WIN32
 
35
#       include "config.h"
 
36
#endif
35
37
/* work around for libc5 */
36
38
/*#include <typedefs_md.h>*/
37
39
#include "gnu_io_LPRPort.h"
40
42
#include <time.h>
41
43
#include <stdio.h>
42
44
#include <string.h>
43
 
#include <sys/ioctl.h>
 
45
#ifndef WIN32
 
46
#       include <sys/ioctl.h>
 
47
#       include <sys/errno.h>
 
48
#       include <sys/param.h>
 
49
#else
 
50
#       include <errno.h>
 
51
#       include "win32termios.h"
 
52
#endif
44
53
#include <sys/types.h>
45
54
#include <sys/stat.h>
46
 
#include <sys/errno.h>
47
 
#include <sys/param.h>
48
55
#include <sys/time.h>
49
56
#include <stdlib.h>
50
57
 
130
137
        }
131
138
        return(JNI_TRUE);
132
139
}
 
140
 
 
141
#if defined (WIN32)
 
142
 
 
143
#define CTL_CODE( DeviceType, Function, Method, Access ) (((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method))
 
144
 
 
145
#define FILE_DEVICE_PARALLEL_PORT       0x00000016
 
146
#define METHOD_BUFFERED                 0
 
147
#define FILE_ANY_ACCESS                 0
 
148
 
 
149
#define IOCTL_PAR_QUERY_INFORMATION CTL_CODE(FILE_DEVICE_PARALLEL_PORT,1,METHOD_BUFFERED,FILE_ANY_ACCESS)
 
150
 
 
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
 
159
 
 
160
int getWin32ParallelStatusFlags(int fd){
 
161
        int status = 0;
 
162
        DWORD count;
 
163
        if(!DeviceIoControl( (HANDLE)fd, IOCTL_PAR_QUERY_INFORMATION, NULL,0, &status, sizeof(status), &count, 0) && count == 1){
 
164
                YACK();
 
165
                return 0;
 
166
        }
 
167
#ifdef DEBUG
 
168
        printf("getWin32ParallelStatusFlags: %d\n", status );
 
169
#endif
 
170
        return status;
 
171
}
 
172
 
 
173
jboolean getWin32ParallelStatus(int fd, int flag){
 
174
        return( (getWin32ParallelStatusFlags(fd) & flag) ? JNI_TRUE : JNI_FALSE);
 
175
}
 
176
#endif
 
177
 
133
178
/*----------------------------------------------------------
134
179
LPRPort.isPaperOut
135
180
   accept:      none
142
187
        jobject jobj)
143
188
{
144
189
 
145
 
        int status;
146
190
        int fd = get_java_var( env, jobj,"fd","I" );
147
191
#if defined (__linux__)
 
192
        int status;
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); 
150
197
#else
151
198
/*  FIXME??  */
152
199
        printf("ParallelImp.c LPGETSTATUS not defined\n");
164
211
JNIEXPORT jboolean JNICALL LPRPort(isPrinterBusy)(JNIEnv *env,
165
212
        jobject jobj)
166
213
{
 
214
        int fd = get_java_var( env, jobj,"fd","I" );
167
215
        int status;
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); 
171
220
#else
172
221
/*  FIXME??  */
173
222
        printf("ParallelImp.c LPGETSTATUS not defined\n");
191
240
JNIEXPORT jboolean JNICALL LPRPort(isPrinterError)(JNIEnv *env,
192
241
        jobject jobj)
193
242
{
194
 
        int status;
195
243
        int fd = get_java_var( env, jobj,"fd","I" );
196
244
#if defined (__linux__)
 
245
        int status;
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 | 
 
250
                                                                           PARALLEL_OFF_LINE |
 
251
                                                                           PARALLEL_POWER_OFF |
 
252
                                                                           PARALLEL_NOT_CONNECTED |
 
253
                                                                           PARALLEL_BUSY); 
199
254
#else
200
255
/*  FIXME??  */
201
256
        printf("ParallelImp.c LPGETSTATUS not defined\n");
213
268
JNIEXPORT jboolean JNICALL LPRPort(isPrinterSelected)(JNIEnv *env,
214
269
        jobject jobj)
215
270
{
216
 
        int status;
217
271
        int fd = get_java_var( env, jobj,"fd","I" );
218
272
#if defined (__linux__)
 
273
        int status;
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); 
221
278
#else
222
279
/*  FIXME??  */
223
280
        printf("ParallelImp.c LPGETSTATUS not defined\n");
237
294
JNIEXPORT jboolean JNICALL LPRPort(isPrinterTimedOut)(JNIEnv *env,
238
295
        jobject jobj)
239
296
{
 
297
#if defined(__linux__)
 
298
        int fd = get_java_var( env, jobj,"fd","I" );
240
299
        int status;
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 );
245
302
#endif
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. */
 
328
#if !defined(WIN32)
271
329
        struct sigaction handler;
272
330
        sigaction( SIGIO, NULL, &handler );
273
331
        if( !handler.sa_handler ) signal( SIGIO, SIG_IGN );
 
332
#endif /* !WIN32 */
274
333
}
275
334
 
276
335
 
291
350
{
292
351
        /*struct termios ttyset;*/
293
352
        const char *filename = (*env)->GetStringUTFChars( env, jstr, 0 );
 
353
#ifdef WIN32
 
354
        int fd = (int)CreateFile( filename, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0 );
 
355
#else
294
356
        int fd = open( filename, O_RDWR | O_NONBLOCK );
 
357
#endif
295
358
        (*env)->ReleaseStringUTFChars( env, jstr, NULL );
296
359
        if( fd < 0 ) goto fail;
297
360
        return (jint)fd;
298
361
 
299
362
fail:
300
 
        throw_java_exception( env, PORT_IN_USE_EXCEPTION, "open",
301
 
                strerror( errno ) );
 
363
        throw_java_exception_system_msg( env, PORT_IN_USE_EXCEPTION, "open" );
302
364
        return -1;
303
365
}
304
366
 
316
378
{
317
379
        int fd = get_java_var( env, jobj,"fd","I" );
318
380
 
 
381
#ifdef WIN32
 
382
        CloseHandle( (HANDLE)fd );
 
383
#else
319
384
        close( fd );
 
385
#endif
320
386
        return;
321
387
}
322
388
 
334
400
        unsigned char byte = (unsigned char)ji;
335
401
        int fd = get_java_var( env, jobj,"fd","I" );
336
402
 
 
403
#ifdef WIN32
 
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;
 
406
#else
337
407
        if( write( fd, &byte, sizeof( unsigned char ) ) >= 0 ) return;
338
 
        throw_java_exception( env, IO_EXCEPTION, "writeByte",
339
 
                strerror( errno ) );
 
408
#endif
 
409
        throw_java_exception_system_msg( env, IO_EXCEPTION, "writeByte" );
340
410
}
341
411
 
342
412
 
353
423
JNIEXPORT void JNICALL LPRPort(writeArray)( JNIEnv *env,
354
424
        jobject jobj, jbyteArray jbarray, jint offset, jint count )
355
425
{
 
426
#ifdef WIN32
 
427
        DWORD countWritten; /* Fixme, should be a loop until all is written */
 
428
        COMMTIMEOUTS timeouts;
 
429
        int errorCount = 0;
 
430
#endif
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 );
359
434
        int i;
360
435
        for( i = 0; i < count; i++ ) bytes[ i ] = body[ i + offset ];
361
436
        (*env)->ReleaseByteArrayElements( env, jbarray, body, 0 );
 
437
#ifdef WIN32
 
438
        /*
 
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
 
442
        */
 
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 );
 
447
        while( count > 0 ){
 
448
                if(!WriteFile( (HANDLE)fd, bytes, count, &countWritten, NULL ) && countWritten == 0){
 
449
                        /*
 
450
                        this are 20 * 2 seconds, in this time a printer (or other parallel device)
 
451
                        should solv all problems like buffer full, etc
 
452
                        */
 
453
                        if(errorCount++ < 20){
 
454
                                Sleep( 20 ); /* make a small pause to execute all other requests in all other threads */
 
455
                                continue;
 
456
                        }
 
457
                        throw_java_exception_system_msg( env, IO_EXCEPTION, "writeArray" );
 
458
                        break;
 
459
                }
 
460
                errorCount = 0;
 
461
                bytes += countWritten;
 
462
                count -= countWritten;
 
463
        }
 
464
#else
362
465
        if( write( fd, bytes, count ) < 0 )
363
 
                throw_java_exception( env, IO_EXCEPTION, "writeArray",
364
 
                        strerror( errno ) );
 
466
                throw_java_exception_system_msg( env, IO_EXCEPTION, "writeArray" );
 
467
#endif
365
468
        free( bytes );
366
469
}
367
470
 
409
512
                        if( ret == 0 ) break;
410
513
                        if( ret < 0 ) return -1;
411
514
                }
 
515
#if defined(WIN32)
 
516
                if(!ReadFile( (HANDLE)fd, buffer + bytes, left, (DWORD *)&ret, NULL )){
 
517
                        YACK();
 
518
                        ret = -1;
 
519
                }
 
520
#else
412
521
                ret = read( fd, buffer + bytes, left );
 
522
#endif
413
523
                if( ret == 0 ) break;
414
524
                if( ret < 0 ) return -1;
415
525
                bytes += ret;
439
549
        bytes = read_byte_array( fd, buffer, 1, 1, timeout );
440
550
        if( bytes < 0 )
441
551
        {
442
 
                throw_java_exception( env, IO_EXCEPTION, "readByte",
443
 
                        strerror( errno ) );
 
552
                throw_java_exception_system_msg( env, IO_EXCEPTION, "readByte" );
444
553
 
445
554
                return -1;
446
555
        }
468
577
        threshold = get_java_var( env, jobj,"threshold","I" );
469
578
        timeout = get_java_var( env, jobj,"threshold","I" );
470
579
 
471
 
        if( length < 1 || length > SSIZE_MAX )
 
580
        if( (size_t) length < 1 || (size_t) length > SSIZE_MAX )
472
581
        {
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 )
480
589
        {
481
 
                throw_java_exception( env, IO_EXCEPTION, "writeByte",
 
590
                throw_java_exception( env, IO_EXCEPTION, "readArray",
482
591
                        "Unable to allocate buffer" );
483
592
 
484
593
                return -1;
488
597
        if( bytes < 0 )
489
598
        {
490
599
                free( buffer );
491
 
                throw_java_exception( env, IO_EXCEPTION, "readArray",
492
 
                        strerror( errno ) );
 
600
                throw_java_exception_system_msg( env, IO_EXCEPTION, "readArray" );
493
601
 
494
602
                return -1;
495
603
        }
555
663
        report("LPRPort:nativeavailable:  ioctl() failed\n");
556
664
        LEAVE( "LPRPort:nativeavailable" );
557
665
*/
558
 
        throw_java_exception( env, IO_EXCEPTION, "nativeavailable",
559
 
                strerror( errno ) );
 
666
        throw_java_exception_system_msg( env, IO_EXCEPTION, "nativeavailable" );
560
667
        return (jint)result;
561
668
}
562
669
 
599
706
        jobject jobj )
600
707
{
601
708
        int fd, ret;
602
 
        unsigned int pflags;
 
709
        unsigned int pflags = 0;
603
710
        fd_set rfds;
604
711
        struct timeval sleep;
605
712
        jboolean interrupted = 0;
627
734
 
628
735
#if defined(LPGETSTATUS)
629
736
                ioctl( fd, LPGETSTATUS, &pflags );
 
737
#elif defined(WIN32)
 
738
                pflags = getWin32ParallelStatusFlags(fd);
630
739
#else
631
740
        /*  FIXME??  */
632
741
        printf("ParallelImp.c LPGETSTATUS is undefined!\n");
637
746
                        PAR_EV_ERROR:
638
747
*/
639
748
 
640
 
#if defined(LP_BUSY)
 
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 );
651
763
*/
 
764
 
 
765
 
652
766
#if defined (__linux__)
653
767
                /* unchanged input, active low */
654
768
                if (pflags&LP_NOPA)   /* unchanged input, active high */
696
810
#endif
697
811
        return(1);
698
812
}
 
813
 
699
814
/*----------------------------------------------------------
700
815
throw_java_exception
701
816
 
710
825
----------------------------------------------------------*/
711
826
void throw_java_exception( JNIEnv *env, char *exc, char *foo, char *msg )
712
827
{
713
 
        char buf[ 60 ];
 
828
#define MSG_SIZE 128
 
829
        char buf[ 128 ];
714
830
        jclass clazz = (*env)->FindClass( env, exc );
715
831
        if( !clazz )
716
832
        {
718
834
                (*env)->ExceptionClear( env );
719
835
                return;
720
836
        }
 
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;
 
840
        }
721
841
#if defined(_GNU_SOURCE)
722
842
        snprintf( buf, 60, "%s in %s", msg, foo );
723
843
#else
728
848
        (*env)->DeleteLocalRef( env, clazz );
729
849
}
730
850
 
 
851
void throw_java_exception_system_msg( JNIEnv *env, char *exc, char *foo )
 
852
{
 
853
#ifdef WIN32
 
854
        char *allocTextBuf;
 
855
        FormatMessage (
 
856
                FORMAT_MESSAGE_ALLOCATE_BUFFER |
 
857
                FORMAT_MESSAGE_FROM_SYSTEM,
 
858
                NULL,
 
859
                GetLastError(),
 
860
                MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
 
861
                (LPSTR)&allocTextBuf,
 
862
                16,
 
863
                NULL );
 
864
        throw_java_exception( env, exc, foo, allocTextBuf );
 
865
        LocalFree(allocTextBuf);
 
866
#else
 
867
        throw_java_exception( env, exc, foo, strerror( errno ) );
 
868
#endif
 
869
}
 
870
/*----------------------------------------------------------
 
871
 report_error
 
872
 
 
873
   accept:      string to send to report as an error
 
874
   perform:     send the string to stderr or however it needs to be reported.
 
875
   return:      none
 
876
   exceptions:  none
 
877
   comments:
 
878
----------------------------------------------------------*/
 
879
void report_error(char *msg)
 
880
{
 
881
#ifndef DEBUG_MW
 
882
        fprintf(stderr, msg);
 
883
#else
 
884
        mexWarnMsgTxt( msg );
 
885
#endif /* DEBUG_MW */
 
886
}
 
887
 
731
888
/*----------------------------------------------------------
732
889
 report
733
890