|
|
- /*
- *
- * Compiz smackpad plugin
- * smackpad.c
- * Copyright (c) 2007 Eugen Feller <eugen.feller@uni-duesseldorf.de>
- *
- * Client message to root window taken from mswitch.c:
- * Copyright : (c) 2007 Robert Carr
- * E-mail : racarr@opencompositing.org
- *
- * This program 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
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- */
- /*
- * Thanks to Michele Campeotto <micampe@micampe.it> and
- * Fernando Herrera <fherrera@onirica.com> for their ideas
- * which helped me to make this plugin.
- */
- /*
- * Almost totally rewrite by Yang Zhe <yangzhe1990@gmail.com>
- */
- #include <compiz-core.h>
- #include "smackpad_options.h"
- #include <X11/Xlib.h>
- #include <math.h>
- #include <limits.h>
- #include <time.h>
- #include <pthread.h>
- #include <stdlib.h>
- #include <stdio.h>
- #define POSITION_FILE "/sys/devices/platform/hdaps/position"
- #define CALIBRATE_FILE "/sys/devices/platform/hdaps/calibrate"
- #define INVERT_FILE "/sys/devices/platform/hdaps/invert"
- int N=400;
- typedef enum
- {
- LEFT,
- RIGHT,
- UP,
- DOWN
- }smackDirection;
- typedef enum
- {
- CALIBRATE,
- POSITION
- }smackpadMisc;
- typedef struct
- {
- int x;
- int y;
- }smackpadPosition;
- static int sensitivityRate=5;
- pthread_t readPositionThread;
- static int readPositionThreadStatus=-1;
- static Bool statusLoop=FALSE;
- static Bool statusPlugin=FALSE;
- static CompScreen *screen=NULL;
- /* prototype definitions */
- static void* smackpadGetPosition (void *data);
- static void smackpadRotate (int dX, int dY);
- static void smackpadUpdateSensitivityRate (CompDisplay *d, CompOption *opt, SmackpadDisplayOptions num);
- static Bool smackpadInitiate (CompDisplay *d, CompAction *ac, CompActionState state, CompOption *option, int nOption);
- static Bool smackpadReadHDAPSData (smackpadMisc misc, Bool invert, smackpadPosition *position);
- static Bool smackpadInitHDAPS (void);
- static CompBool smackpadInitObject (CompPlugin *p, CompObject *o);
- static Bool smackpadInitDisplay (CompPlugin *p, CompDisplay *d);
- static Bool smackpadInitScreen (CompPlugin *p, CompScreen *s);
- static void smackpadFini (CompPlugin *p);
- static Bool
- smackpadReadHDAPSData (smackpadMisc misc,
- Bool invert,
- smackpadPosition *position)
- {
- char buf[255];
- FILE *file=NULL;
-
- switch(misc)
- {
- case CALIBRATE:
- file = fopen(CALIBRATE_FILE, "r");
- break;
- case POSITION:
- file = fopen(POSITION_FILE, "r");
- break;
- }
-
- if (file == NULL)
- return FALSE;
-
- fread(buf, 255, 1, file);
- fclose(file);
-
- /* if(invert)
- sscanf(buf, "(%d,%d)", &position->y, &position->x);
- else
- sscanf(buf, "(%d,%d)", &position->x, &position->y);
- */
- sscanf(buf, "(%d,%d)", &position->x, &position->y);
-
- return TRUE;
-
- }
- static void
- smackpadRotate (int dX,
- int dY)
- {
- XEvent xev;
- xev.xclient.type = ClientMessage;
- xev.xclient.display = screen->display->display;
- xev.xclient.format = 32;
- xev.xclient.message_type = screen->display->desktopViewportAtom;
- xev.xclient.window = screen->root;
- xev.xclient.data.l[0] = (screen->x+dX)*screen->width;
- xev.xclient.data.l[1] = (screen->y+dY)*screen->height;
- xev.xclient.data.l[2] = 0;
- xev.xclient.data.l[3] = 0;
- xev.xclient.data.l[4] = 0;
-
- XSendEvent(screen->display->display, screen->root, FALSE,
- SubstructureRedirectMask | SubstructureNotifyMask, &xev);
- }
- static void*
- smackpadGetPosition (void *misc)
- {
- struct timespec sleepTimer;
- smackpadPosition *positions;
- int i, w, x, *maxstack, *maxidx, maxbottom, maxtop, maxcnt, *minstack, *minidx, minbottom, mintop, mincnt;
- int direction = 0;
- int tot = 0;
- #ifdef DEBUG2
- int j;
- #endif
- float avg;
- sleepTimer.tv_sec=0;
- sleepTimer.tv_nsec=1000000; /* 1ms */
-
- positions = malloc( N*sizeof(smackpadPosition) );
- maxstack = malloc( N*sizeof(int) ); maxidx = malloc( N*sizeof(int) ); maxbottom = 0; maxtop = -1; maxcnt = 0;
- minstack = malloc( N*sizeof(int) ); minidx = malloc( N*sizeof(int) ); minbottom = 0; mintop = -1; mincnt = 0;
- if (positions == NULL || maxstack == NULL || maxidx == NULL || minstack == NULL || minidx == NULL) return NULL;
- for (i = 0; i < N; ++i) {
- if(!smackpadReadHDAPSData(1,TRUE,positions+i)) return NULL;
- x = (positions+i)->x;
- tot += x;
- while (maxcnt > 0 && x >= maxstack[maxtop]) {
- maxtop = (maxtop + N - 1) % N;
- --maxcnt;
- }
- maxtop = (maxtop + 1) % N;
- maxstack[maxtop] = x;
- maxidx[maxtop] = i;
- ++maxcnt;
- while (mincnt > 0 && x <= minstack[mintop]) {
- mintop = (mintop + N - 1) % N;
- --mincnt;
- }
- mintop = (mintop + 1) % N;
- minstack[mintop] = x;
- minidx[mintop] = i;
- ++mincnt;
- }
- i = 0;
- while (statusLoop)
- {
- avg = (float)tot / N;
- w = maxstack[maxbottom] - minstack[minbottom];
- tot -= (positions+i)->x;
- if(!smackpadReadHDAPSData(1,TRUE,positions+i)) return NULL;
- x = (positions+i)->x;
- tot += x;
- if (minidx[minbottom] == i) {
- minbottom = (minbottom + 1) % N;
- --mincnt;
- }
- if (maxidx[maxbottom] == i) {
- maxbottom = (maxbottom + 1) % N;
- --maxcnt;
- }
- while (maxcnt > 0 && x >= maxstack[maxtop]) {
- maxtop = (maxtop + N - 1) % N;
- --maxcnt;
- }
- maxtop = (maxtop + 1) % N;
- maxstack[maxtop] = x;
- maxidx[maxtop] = i;
- ++maxcnt;
- while (mincnt > 0 && x <= minstack[mintop]) {
- mintop = (mintop + N - 1) % N;
- --mincnt;
- }
- mintop = (mintop + 1) % N;
- minstack[mintop] = x;
- minidx[mintop] = i;
- ++mincnt;
- #ifdef DEBUG2
- printf("%d\n", w);
- #endif
- if (w <= 2) {
- if (fabs(x - avg) > 3)
- direction = (x > avg) ? 1 : -1;
- else
- direction = 0;
- if (fabs(x - avg) > sensitivityRate) {
- if (direction == 0)
- direction = (x > avg) ? 1 : -1;
- #ifdef DEBUG2
- printf("avg: %2f, x: %d\n", avg, x);
- for (j = (i+490)%N; j != i; j = (j+1)%N)
- printf("(%d, %d), ", (positions+j)->x, j);
- printf("(%d, %d)\n", (positions+i)->x, i);
- #endif
- smackpadRotate(direction, 0);
- }
- }
- else
- direction = 0;
- i = (i+1) % N;
- nanosleep(&sleepTimer,NULL);
- }
-
- free(maxstack); free(maxidx);
- free(minstack); free(minidx);
- return NULL;
- }
- static void
- smackpadUpdateSensitivityRate (CompDisplay *d,
- CompOption *opt,
- SmackpadDisplayOptions num)
- {
- sensitivityRate=smackpadGetSensitivityRate(d);
- }
- static Bool
- smackpadInitHDAPS (void)
- {
- FILE *file=NULL;
- file=fopen(POSITION_FILE,"r");
-
- if(file!=NULL)
- {
- fclose(file);
- return TRUE;
- }
-
- return FALSE;
- }
- static Bool
- smackpadInitiate (CompDisplay *d,
- CompAction *ac,
- CompActionState state,
- CompOption *option,
- int nOption)
- {
- Bool testHdapsStatus=smackpadInitHDAPS();
-
- if(testHdapsStatus && !statusPlugin)
- {
- statusLoop=TRUE;
- statusPlugin=TRUE;
- readPositionThreadStatus=pthread_create(&readPositionThread,NULL,smackpadGetPosition,NULL);
- }
- else if(testHdapsStatus && screen)
- {
- statusLoop=FALSE;
- statusPlugin=FALSE;
- pthread_join(readPositionThread,NULL);
- }
-
- return TRUE;
- }
- static Bool
- smackpadInitScreen (CompPlugin *p,
- CompScreen *s)
- {
- screen=s;
-
- return TRUE;
- }
- static Bool
- smackpadInitDisplay (CompPlugin *p,
- CompDisplay *d)
- {
- smackpadSetSensitivityRateNotify(d,smackpadUpdateSensitivityRate);
- smackpadSetInitiateKeyInitiate(d, smackpadInitiate);
-
- return TRUE;
- }
- static CompBool
- smackpadInitObject (CompPlugin *p,
- CompObject *o)
- {
- static InitPluginObjectProc dispTab[] = {
- (InitPluginObjectProc) 0, /* InitCore */
- (InitPluginObjectProc) smackpadInitDisplay,
- (InitPluginObjectProc) smackpadInitScreen,
- };
- RETURN_DISPATCH (o, dispTab, ARRAY_SIZE (dispTab), TRUE, (p, o));
- }
- static void
- smackpadFini (CompPlugin *p)
- {
- if(readPositionThreadStatus==0)
- {
- statusLoop=FALSE;
- pthread_join(readPositionThread,NULL);
- }
- }
- CompPluginVTable smackpadVTable = {
- "smackpad",
- 0,
- 0,
- smackpadFini,
- smackpadInitObject,
- 0,
- 0,
- 0
- };
- CompPluginVTable *
- getCompPluginInfo (void)
- {
- return &smackpadVTable;
- }
复制代码 |
|