×Nö~Ë­­ª|ç_=ێtÛnõÓ_4Ó

Attachment: rotate
Description: Binary data

/* -*-  tab-width:4; c-basic-offset:4  -*-
 * rotate.c -- determine Freerunner orientation.
 * Author   -- Chris Ball <[EMAIL PROTECTED]>
 *
 * This file is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the
 * Free Software Foundation; either version 2, or (at your option) any
 * later version.
 */

#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <X11/Xlib.h>
#include <X11/extensions/Xrandr.h>
#include <pthread.h>
#include <sys/time.h>

#define EVENT_PATH            "/dev/input/event3"
#define EVENT_LEN             5
#define ORIENTATION_NORMAL    0
#define ORIENTATION_LEFT      1
#define ORIENTATION_RIGHT     2
#define ORIENTATION_INVERTED  3


static Display  *display;
static Window   rootWindow;

static char evenBuffer[EVENT_LEN];
static int tail,head;
static int bDebug;

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

int timeval_subtract (struct timeval *result, struct timeval *x, struct timeval *y)
{
   if (x->tv_usec < y->tv_usec) {
      int nsec = (y->tv_usec - x->tv_usec) / 1000000 + 1;
      y->tv_usec -= 1000000 * nsec;
      y->tv_sec += nsec;
   }
   if (x->tv_usec - y->tv_usec > 1000000) {
      int nsec = (x->tv_usec - y->tv_usec) / 1000000;
      y->tv_usec += 1000000 * nsec;
      y->tv_sec -= nsec;
   }

   result->tv_sec = x->tv_sec - y->tv_sec;
   result->tv_usec = x->tv_usec - y->tv_usec;

   return x->tv_sec < y->tv_sec;
}


void *pEvenThrd( void *ptr )
{
   FILE *eventfp = (FILE *)ptr;
   int state;
   int curline;
   unsigned short buffer[8 * 7];
   int i;
   unsigned short x=0;
   unsigned short y=0;
   unsigned short z=0;
   int oldrotation = -1;

    /* The raw data looks like:
   *
   * portrait
   * 2ca3 48ab 43bf 000d 0000 0000 0000 0000 # start of packet
   * 2ca3 48ab 687b 000d 0002 0000 005a 0000 # X
   * 2ca3 48ab 68a8 000d 0002 0001 fc34 ffff # Y
   * 2ca3 48ab 68c1 000d 0002 0002 0048 0000 # Z
   * 2ca3 48ab 68c6 000d 0000 0000 0000 0000 # start of packet
   *
   * landscape
   * 2ca5 48ab 0f8f 0008 0002 0000 03cc 0000 # X
   * 2ca5 48ab 0fc4 0008 0002 0001 0168 0000 # Y
   * 2ca5 48ab 0fde 0008 0002 0002 005a 0000 # Z
    */


   while (1)
   {
      /* We have to read enough to guarantee a full packet, since if
      * we try to read one line at a time we'll end up missing lines. */
      fread (buffer, 1, sizeof (buffer), eventfp);
      state = 0;
      /* We get 7 packets at once, to ensure that we have 3 good ones.
      * Each of those has 8*2 bytes inside it. */
      for (i = 0; i <= 6; i++)
      {
         curline = i * 8;
         switch (state)
         {
               /* State machine:
            * 0: Find a new packet
            * 1: record X (jump to 0 on error)
            * 2: record Y (jump to 0 on error)
            * 3: record Z (jump to 0 on error), process packet, reset
               */
            case 0:
               if (buffer[curline + 4] == 0x0 && buffer[curline + 5] == 0x0) {
                  x = y = z = 0;
                  state = 1;
               }
               break;
            case 1:
               if (!(buffer[curline + 4] == 0x2 && buffer[curline + 5] == 0x0)) {
                  //printf("EXPECTED: 2 0: %x %x\n",
                  //      buffer[curline + 4], buffer[curline + 5]);
                  state = 0;
                  break;
               }
               x = buffer[curline + 7];
               state++;
               break;
            case 2:
               if (!(buffer[curline + 4] == 0x2 && buffer[curline + 5] == 0x1)) {
                 // printf("EXPECTED: 2 1: %x %x\n",
                 //       buffer[curline + 4], buffer[curline + 5]);
                  state = 0;
                  break;
               }
               y = buffer[curline + 7];
               state++;
               break;
            case 3:
               if (!(buffer[curline + 4] == 0x2 && buffer[curline + 5] == 0x2)) {
                 // printf("EXPECTED: 2 2: %x %x\n",
                 //       buffer[curline + 4], buffer[curline + 5]);
                  state = 0;
                  break;
               }
               z = buffer[curline + 7];
               /*
               * We finished a packet.  Process it.
               * We test the final 4 bytes for:
               * ffff/ffff -- portrait
               * 0000/ffff -- portrait
               * 0000/0000 -- landscape
               * ffff/0000 -- landscape
               *
               * We might do better by using the previous eight bytes and
               * diagonal quadrants instead of the final four bytes, but
               * this seems to work out well for now.
               */
               if (y == 0xffff && (x == 0xffff || x == 0x0))
               {
                  if (oldrotation!=ORIENTATION_NORMAL)
                  {
                     evenBuffer[head]=ORIENTATION_NORMAL;
                     head = (head+1) % EVENT_LEN;

                     oldrotation=ORIENTATION_NORMAL;
                  }
               }
               else if (x == 0x0 && y == 0x0)
               {
                  if (oldrotation!=ORIENTATION_LEFT)
                  {
                     evenBuffer[head]=ORIENTATION_LEFT;
                     head = (head+1) % EVENT_LEN;
                     oldrotation=ORIENTATION_LEFT;
                  }
               }
               else if (x == 0xffff && y == 0x0)
               {
                  if (oldrotation!=ORIENTATION_RIGHT)
                  {
                     evenBuffer[head]=ORIENTATION_RIGHT;
                     head = (head+1) % EVENT_LEN;

                     oldrotation=ORIENTATION_RIGHT;
                  }
               }
               break;

            default:
            {
               /* Shouldn't get here. */
               fprintf(stderr, "We hit the default case; bailing out.\n");
            }
         }
      }
      usleep(100);
   }
}

void *pWaitThrd( void *ptr )
{

      while (1)
      {
         if (bDebug)
            printf ("waitThrd: lock\n");

         
         pthread_mutex_lock( &mutex );
   
         //Waiting for a new possition
         while (tail==head)
           usleep (1000);
         
         if (bDebug)
            printf ("waitThrd: unlock\n");
         
         //Let then main process handle the new possition
         pthread_mutex_unlock( &mutex );
      }
}

void set_rotation (int rotation) {
   Rotation r_to,r;
   int screen = -1;
   int do_rotate=1;
   XRRScreenConfiguration * config;
   int current_size=0;

   switch (rotation)
   {
      case 0:
         r_to=RR_Rotate_0;
         break;
      case 1:
         r_to=RR_Rotate_90;
         break;
      case 2:
         r_to=RR_Rotate_270;
         break;
      case 3:
         r_to=RR_Rotate_180;
         break;
      default:
         do_rotate=0;
         break;
   }
   if(do_rotate) {
      display = XOpenDisplay(":0");
      if (display == NULL) {
         fprintf (stderr, "Can't open display %s\n", XDisplayName(":0"));
         exit (1);
      }

      screen = DefaultScreen(display);
      rootWindow = RootWindow(display, screen);
      XRRRotations(display, screen, &r);
      config = XRRGetScreenInfo(display, rootWindow);
      current_size = XRRConfigCurrentConfiguration (config, &r);
      XRRSetScreenConfig(display, config, rootWindow, current_size, r_to, CurrentTime);

      /* Sleep for two seconds to give randr a chance to catch up. */
//      sleep(2);
   }
}

int main (int argc, char *argv[])
{
   FILE *eventfp,*screenfp;
   int rotation = -1;
   int oldrotation = -1;
   int n=0;
   pthread_t thread1;
   pthread_t waitThread;
   bDebug=0;
   char strBrightness[30];
   
   struct timeval timeres,start, stop;

   
   argc--; argv++;
   for (n=0;n<argc;n++)
   {
      if (!strcmp (argv[n],"--debug"))
         bDebug=1;
   }
   
   memset (strBrightness,0,sizeof (strBrightness));
   /* Does this always hold on OpenMoko distros? */
   putenv("DISPLAY=:0");

   eventfp = fopen(EVENT_PATH, "rb");
   if (eventfp == NULL) {
      fprintf(stderr, "Couldn't open file.\n");
      exit(1);
   }

   pthread_create( &thread1, NULL, pEvenThrd, (void*) eventfp);
   pthread_create( &waitThread, NULL, pWaitThrd, NULL);

   screenfp = fopen ("/sys/class/backlight/pcf50633-bl/brightness","r+");
   setvbuf ( screenfp, NULL , _IONBF, 0);
   if (screenfp == NULL )
   {
      fprintf(stderr, "Couldn't open file brightness.\n");
      exit(1);
   }

   gettimeofday(&start, NULL);
   while (1)
   {
      if (bDebug)
         printf ("main: lock\n");
      
      //Waiting for a new possition
      pthread_mutex_lock( &mutex );

     gettimeofday(&start, NULL);
     rotation = evenBuffer[tail];
     tail = (tail+1) % EVENT_LEN;
     do
     {
        gettimeofday(&stop, NULL);
        timeval_subtract(&timeres, &stop, &start);
     }while (timeres.tv_sec<1 && head==tail);

     if (head==tail)
     {
        if (oldrotation!=rotation)
        {
           fseek (screenfp, 0L, SEEK_SET);
           fread (strBrightness,sizeof (strBrightness),3,screenfp);
           if (bDebug)
            printf ("brightness=%s",strBrightness);
           fprintf(screenfp,"0");
           fflush (screenfp);
           set_rotation(rotation);
           sleep (1);
           fprintf(screenfp,"%s",strBrightness);
           fflush (screenfp);
           gettimeofday(&start, NULL);
           oldrotation=rotation;
        }
     }
      pthread_mutex_unlock( &mutex );
      if (bDebug)
         printf ("main: unlock\n");
   }
}
_______________________________________________
Openmoko community mailing list
community@lists.openmoko.org
http://lists.openmoko.org/mailman/listinfo/community

Reply via email to