/** * @file * * @ingroup libmisc_fb_mw Input Devices for MicroWindows * * @brief MicroWindows UID * * This module implements the input devices interface used by MicroWindows * in an embedded system environment. It uses the RTEMS message queue as * the repository for the messages posted by the devices registered. */ /* * Copyright (c) 2000 - Rosimildo da Silva */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #include static rtems_id queue_id = 0; static int open_count = 0; /* #define MW_DEBUG_ON 1 */ /* open a message queue with the kernel */ int uid_open_queue( const char *q_name, int flags RTEMS_UNUSED, size_t max_msgs ) { rtems_status_code status; /* * For the first device calling this function we would create the queue. * It is assumed that this call is done at initialization, and no concerns * regarding multi-threading is taken in consideration here. */ if ( open_count ) { open_count++; return 0; } status = rtems_message_queue_create( rtems_build_name( q_name[0], q_name[1], q_name[2], q_name[3] ), max_msgs, sizeof( struct MW_UID_MESSAGE ), RTEMS_FIFO | RTEMS_LOCAL, &queue_id ); if ( status != RTEMS_SUCCESSFUL ) { #ifdef MW_DEBUG_ON printk( "UID_Queue: error creating queue: %d\n", status ); #endif return -1; } #ifdef MW_DEBUG_ON printk( "UID_Queue: id=%X\n", queue_id ); #endif open_count++; return 0; } /* close message queue */ int uid_close_queue( void ) { if ( open_count == 1 ) { rtems_message_queue_delete( queue_id ); queue_id = 0; } open_count--; return 0; } /* reads for a message from the device */ int uid_read_message( struct MW_UID_MESSAGE *m, unsigned long timeout ) { rtems_status_code status; size_t size = 0; int wait = (timeout != 0); int ticks = RTEMS_MICROSECONDS_TO_TICKS(timeout * 1000); if (timeout == (unsigned long) -1) { ticks = RTEMS_NO_TIMEOUT; } else if (timeout && ticks == 0) { /* if timeout greater than 0 and smaller than a tick, round up to avoid * unintentionally RTEMS_NO_TIMEOUT */ ticks = 1; } status = rtems_message_queue_receive( queue_id, (void*)m, &size, wait ? RTEMS_WAIT : RTEMS_NO_WAIT, ticks ); if( status == RTEMS_SUCCESSFUL ) { return size; } else if( ( status == RTEMS_UNSATISFIED ) || ( status == RTEMS_TIMEOUT ) ) { rtems_set_errno_and_return_minus_one( ETIMEDOUT ); } /* Here we have one error condition */ #ifdef MW_DEBUG_ON printk( "UID_Queue: error reading queue: %d\n", status ); #endif return -1; } /* * add a message to the queue of events. This method can be used to * simulate hardware events, and it can be very handy during development * a new interface. */ int uid_send_message( struct MW_UID_MESSAGE *m ) { rtems_status_code status; status = rtems_message_queue_send( queue_id, ( void * )m, sizeof( struct MW_UID_MESSAGE ) ); return (status == RTEMS_SUCCESSFUL) ? 0 : -1; } /* * register the device to insert events to the message * queue named as the value passed in q_name */ int uid_register_device( int fd, const char *q_name ) { return ioctl( fd, MW_UID_REGISTER_DEVICE, q_name ); } /* tell this device to stop adding events to the queue */ int uid_unregister_device( int fd ) { return ioctl( fd, MW_UID_UNREGISTER_DEVICE, NULL ); } /* set the keyboard */ int uid_set_kbd_mode( int fd, int mode, int *old_mode ) { if (ioctl( fd, MV_KDGKBMODE, old_mode) < 0) { return -1; } if (ioctl(fd, MV_KDSKBMODE, mode ) < 0 ) { return -1; } return 0; }