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