#include <rtl.h>
#include <rtl_posixio.h>

#include "include/vga.h"
#include "include/kbd.h"
#include "include/rtl_screen.h"

MODULE_AUTHOR("Miguel Masmano Tello <mmasmano@disca.upv.es>");
MODULE_DESCRIPTION("RT_Terminal");

MODULE_LICENSE("GPL");

//////////////////////////////////
//// POSIX TERMINAL FUNCTIONS ////
//////////////////////////////////

// RT_TTY_MAJOR defines the major number used by this device
#define RT_TTY_MAJOR 20

// This function can be implemented using a proccess running on user mode
// which read from keyboard

static ssize_t tty_read (struct rtl_file *file, char *buffer, size_t size, 
		         loff_t *s){
  int n, temp;
  for (n = 0; n < size; n++) {
    temp = (char) rt_terminal_getchar ();
    if (temp == -1)
      return n;
    buffer [n] = temp;
  }
  return size;
}

static ssize_t tty_write (struct rtl_file *file, const char *buffer, 
		          size_t size, loff_t *s){
  return rt_terminal_putstring ((char *)buffer, size);  
}

static int tty_open (struct rtl_file *file){
  MOD_INC_USE_COUNT;
  return 0;
}

static int tty_release (struct rtl_file *file){
  MOD_DEC_USE_COUNT;
  return 0;
}

static struct rtl_file_operations rtl_tty_fops = {
  NULL,
  tty_read,
  tty_write,
  NULL,
  NULL,
  tty_open,
  tty_release
};

/////////////////////////////////////////////////////

int init_module(void){

  if (rtl_register_chrdev (RT_TTY_MAJOR, "rt_tty", &rtl_tty_fops)) {
    printk ("RT_TTY: unable to get RTLinux major %d\n", RT_TTY_MAJOR);
    return -EIO;
  }
  if (init_vga () != 0) return -1;
  if (init_rtl_screen ()!= 0) return -1;
  if (init_kbd() != 0) return -1;

  return 0;
}

void cleanup_module(void){
  close_rtl_screen ();
  close_kbd ();
  rtl_unregister_chrdev(RT_TTY_MAJOR, "rt_tty");
}
