×Nö~˪|ç_=ÛtÛnõÓ_4Ó
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 [email protected] http://lists.openmoko.org/mailman/listinfo/community

