  //=========================================================
  //  MusE
  //  Linux Music Editor
  //  $Id: rtctimer.cpp,v 1.1.2.2 2004/12/25 21:03:59 spamatica Exp $
  //
  //  Most code moved from midiseq.cpp by Werner Schweer.
  //
  //  (C) Copyright 2004 Robert Jonsson (rj@spamatica.se)
  //  (C) Copyright -2004 Werner Schweer (werner@seh.de)
  //=========================================================
        
#include <linux/version.h>
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
#include <linux/spinlock.h>
#include <linux/mc146818rtc.h>
#else
#include <linux/rtc.h>
#endif
#include <stdio.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <poll.h>
  
  
#include "rtctimer.h"
#include "globals.h"
#include "gconfig.h"
  
  
  RtcTimer::RtcTimer()
    {
    }
    
  RtcTimer::~RtcTimer()
    {
    }
  
  int RtcTimer::initTimer()
    {
    if(TIMER_DEBUG)
      printf("RtcTimer::initTimer()\n");
      timerFd = -1;
      doSetuid();
      
      timerFd = ::open("/dev/rtc", O_RDONLY);
      if (timerFd == -1) {
            fprintf(stderr, "fatal error: open /dev/rtc failed: %s\n",
               strerror(errno));
            if (!debugMode) {
                  //if(failRTC) {
                            //ErrorHandler::die("Friggin bad!"); error!!
                  //          exit(1);
                  //          }
                  //else {
                            fprintf(stderr, "arg: -r given, will keep going anyway, beware, timing will suffer!\n");
                   //         }
                  }
            undoSetuid();
            return timerFd;
            }
    if (setTimerTicks(config.rtcTicks)) {
            if (ioctl(timerFd, RTC_PIE_ON, 0) == -1) {
                  perror("MidiThread: start: RTC_PIE_ON failed");
                  undoSetuid();
                  return -1;
                  }
            }
    return timerFd;
    }
  
  bool RtcTimer::setTimerResolution(int resolution)
    {
    if(TIMER_DEBUG)
      printf("RtcTimer::setTimerResolution\n");
    return true;    
    }
  
  bool RtcTimer::setTimerTicks(int tick)
    {
    int rc = ioctl(timerFd, RTC_IRQP_SET, config.rtcTicks);
    if (rc == -1) {
            fprintf(stderr, "cannot set tick on /dev/rtc: %s\n",
               strerror(errno));
            fprintf(stderr, "precise timer not available\n");
            close(timerFd);
            if (!debugMode)
                  exit(-1);
            timerFd = -1;
            //setPollWait(10);  // 10 msec
            //realRtcTicks = 100;
            return false;
            }    printf("RtcTimer::setTimerTicks\n");
    }
  
  int  RtcTimer::getTimerResoltution()
    {
    }
        
  bool RtcTimer::startTimer()
    {
    if(TIMER_DEBUG)
      printf("RtcTimer::startTimer\n");
      if (timerFd == -1) {
            if (!debugMode) {
                  fprintf(stderr, "fatal error: setRtcTicks(): no rtc timer avail.\n");
                  //if(failRTC) {
                  //          exit(-1);
                  //          }
                  }
            //setPollWait(10);  // 10 msec
            //realRtcTicks = 100;
            return false;
            }


    return true;
    }
  
  bool RtcTimer::stopTimer()
    {
    if(TIMER_DEBUG)
      printf("RtcTimer::stopTimer\n");
    if (timerFd != -1) {
          ioctl(timerFd, RTC_PIE_OFF, 0);
          ::close(timerFd);
          timerFd = -1;
          }
    return true;
    }
  
  unsigned long RtcTimer::getTimerTicks()
    {
    if(TIMER_DEBUG)
      printf("getTimerTicks()\n");
    unsigned long nn;
    if (read(timerFd, &nn, sizeof(unsigned long)) != sizeof(unsigned long)) {
                    perror("rtc timer read error");
                    exit(-1);
                    }
    }
