summaryrefslogblamecommitdiffstats
path: root/cpukit/libmisc/fb/mw_uid.c
blob: c3933d6e9917595e1bb9d6be9d53be3dee8d7b84 (plain) (tree)
1
2
3
4
5
6
7
8
9
10

        
  
                                                        
  

                          
                                                                          

                                                                         
   
 



                                          



                    




                      

                         
                         
 

                                





                                          

                     
                                 

                      
 





























                                                                            





                           


                                           








                                                                       
                             
                                          









                                                                           





                                       
        


                                    
                 
                                                                               
                                                       

                                        


                                                             


            
  
                                                                   





                                                                        


                                                             

 
  
                                                      
                                            














                                                         






                                               
 
/**
 * @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 <stdio.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <errno.h>
#include <rtems.h>

#include <rtems/mw_uid.h>
#include <rtems/seterr.h>

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;
}