Ón7~Ë­­ª{ó½:óŽ¶ÛmõÓ_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;


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;
                  }
               }
               else 
                  fprintf(stderr, "Unhandled orientation\n");
               
               break;
               
            default:
               /* Shouldn't get here. */
               fprintf(stderr, "We hit the default case; bailing out.\n");
         }
      }
      usleep(100);
   }
}


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  iret1;
   pthread_t thread1;
   
   struct timeval timeres,start, stop;
         
   /* 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);
   }
   
   iret1 = pthread_create( &thread1, NULL, pEvenThrd, (void*) eventfp);
   
   screenfp = fopen ("/sys/class/backlight/pcf50633-bl/brightness","w");
   if (screenfp == NULL )
   {
      fprintf(stderr, "Couldn't open file brightness.\n");
      exit(1);
   }

   gettimeofday(&start, NULL);
   while (1) 
   {          
      if (head!=tail)   
      {  
         gettimeofday(&start, NULL);
         rotation = evenBuffer[tail];
         tail = (tail+1) % EVENT_LEN;
         do
         {       
            gettimeofday(&stop, NULL);
            timeval_subtract(&timeres, &stop, &start);
         }while (timeres.tv_sec<2 && head==tail);
                       
         if (head==tail)
         {
            if (oldrotation!=rotation)
            {      
               fprintf(screenfp,"0");
               fflush (screenfp);
               set_rotation(rotation);
               sleep (2);
               fprintf(screenfp,"63");
               fflush (screenfp);   
               gettimeofday(&start, NULL);
               oldrotation=rotation;
            }
         }
      }
   }
}
_______________________________________________
Openmoko community mailing list
community@lists.openmoko.org
http://lists.openmoko.org/mailman/listinfo/community

Reply via email to