⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 helio.c

📁 linux下的图形界面开发minigui最新源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/*** $Id: helio.c,v 1.16 2003/09/04 03:38:25 weiym Exp $**** helio.c: Low Level Input Engine for Helio Touch Panel** ** Copyright (C) 2000, Wei YongMing ** Copyright (C) 2000, BluePoint Software.**** Created by Wei YongMing, 2001/01/17*//*** 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.**** You should have received a copy of the GNU General Public License** along with this program; if not, write to the Free Software** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA*/#include <stdio.h>#include <errno.h>#include <unistd.h>#include <fcntl.h>#include <sys/ioctl.h>#include <sys/poll.h>#include "common.h"#ifdef _HELIO_IAL#include "misc.h"#include "ial.h"#include "helio.h"static unsigned char state [NR_KEYS];static int tp_fd = -1;static int btn_fd;static char btn_state=0;static int tp_px=0, tp_py=0, tp_pz=0, tp_pb=0;static int enable_coor_transf = 1;#define TPH_DEV_FILE "/dev/tpanel"#define BTN_DEV_FILE "/dev/buttons"/* define if have helio buttons */#define _HELIO_BUTTONS  1#define _TP_HELIO       1#undef  _TP_TSBREF#define TRANS_PER_PIXEL 4#define BUTTON_L        4#define DATACHANGELIMIT 50typedef struct{    /*     * Coefficients for the transformation formulas:     *     *     m = (ax + by + c) / s     *     n = (dx + ey + f) / s     *     * These formulas will transform a device point (x, y) to a     * screen point (m, n) in fractional pixels.  The fraction     * is 1 / TRANS_PER_PIXEL.     */    int a, b, c, d, e, f, s;} TRANSF_COEF;    static TRANSF_COEF tc;static int GetPointerCalibrationData(void){    /*     * Read the calibration data from the calibration file.     * Calibration file format is seven coefficients separated by spaces.     */    /* Get pointer calibration data from this file */    const char cal_filename[] = "/etc/pointercal";    int items;    FILE* f = fopen(cal_filename, "r");    if ( f == NULL ) {        /* now if we can't open /etc/pointercal, we should launch an application         * to calibrate touch panel. so we should disable enable_coor_transf         * so that the application could get raw data from touch panel          */        enable_coor_transf = 0;        return 0;    }    items = fscanf(f, "%d %d %d %d %d %d %d",        &tc.a, &tc.b, &tc.c, &tc.d, &tc.e, &tc.f, &tc.s);    if ( items != 7 ) {    	fprintf(stderr, "Improperly formatted pointer calibration file %s.\n", cal_filename);        return -1;    }    return 0;}static POINT DeviceToScreen(POINT p){    /*     * Transform device coordinates to screen coordinates.     * Take a point p in device coordinates and return the corresponding     * point in screen coodinates.     * This can scale, translate, rotate and/or skew, based on the     * coefficients calculated above based on the list of screen     * vs. device coordinates.     */    static POINT prev;    /* set slop at 3/4 pixel */    const short slop = TRANS_PER_PIXEL * 3 / 4;    POINT new, out;    /* transform */    new.x = (tc.a * p.x + tc.b * p.y + tc.c) / tc.s;    new.y = (tc.d * p.x + tc.e * p.y + tc.f) / tc.s;    /* hysteresis (thanks to John Siau) */    if ( abs(new.x - prev.x) >= slop )        out.x = (new.x | 0x3) ^ 0x3;    else        out.x = prev.x;    if ( abs(new.y - prev.y) >= slop )        out.y = (new.y | 0x3) ^ 0x3;    else        out.y = prev.y;    prev = out;    return out;}static int PD_Open(void){     /*     * open up the touch-panel device.     * Return the fd if successful, or negative if unsuccessful.     */#ifndef _TP_HELIO    struct scanparam s;    int settle_upper_limit;    int result;#endif    tp_fd = open(TPH_DEV_FILE, O_RDONLY);    if (tp_fd < 0) {    	fprintf(stderr, "Error %d opening touch panel\n", errno);        return -1;    }#ifdef _TP_TSBREF    return tp_fd;#endif#ifndef _TP_HELIO    /* set interval to 5000us (200Hz) */    s.interval = 1000;    /*     * Upper limit on settle time is approximately (scan_interval / 5) - 60     * (5 conversions and some fixed overhead)     * The opmtimal value is the lowest that doesn't cause significant     * distortion.     * 50% of upper limit works well on my Clio.  25% gets into distortion.     */    settle_upper_limit = (s.interval / 5) - 60;    s.settletime = settle_upper_limit * 50 / 100;    result = ioctl(tp_fd, TPSETSCANPARM, &s);    if ( result < 0 )    	fprintf(stderr, "Error %d, result %d setting scan parameters.\n", result, errno);#endif    if (enable_coor_transf) {         if (GetPointerCalibrationData() < 0) {            close (tp_fd);            return -1;        }    }    return tp_fd;}static void PD_Close(void){     /* Close the touch panel device. */    if (tp_fd > 0)        close(tp_fd);    tp_fd = -1;}static int PD_Read(int *px, int *py, int *pz, int *pb){    /*     * Read the tpanel state and position.     * Returns the position data in x, y, and button data in b.     * Returns -1 on error.     * Returns 0 if no new data is available.     * Returns 1 if position data is relative (i.e. mice).     * Returns 2 if position data is absolute (i.e. touch panels).     * Returns 3 if position data is not available, but button data is.     * This routine does not block.     *     * Unlike a mouse, this driver returns absolute postions, not deltas.     */    /* If z is below this value, ignore the data. */    /* const int low_z_limit = 900; EVEREX*/#ifndef _TP_HELIO    const int low_z_limit = 815;#endif    /*     * I do some error masking by tossing out really wild data points.     * Lower data_change_limit value means pointer get's "left behind"     * more easily.  Higher value means less errors caught.     * The right setting of this value is just slightly higher than     * the number of units traversed per sample during a "quick" stroke.     */#ifndef _TP_HELIO    const int data_change_limit = DATACHANGELIMIT;#endif    static int have_last_data = 0;    static int last_data_x = 0;    static int last_data_y = 0;    /*     * Thanks to John Siau <jsiau@benchmarkmedia.com> for help with the     * noise filter.  I use an infinite impulse response low-pass filter     * on the data to filter out high-frequency noise.  Results look     * better than a finite impulse response filter.     * If I understand it right, the nice thing is that the noise now     * acts as a dither signal that effectively increases the resolution     * of the a/d converter by a few bits and drops the noise level by     * about 10db.     * Please don't quote me on those db numbers however. :-)     * The end result is that the pointer goes from very fuzzy to much     * more steady.  Hysteresis really calms it down in the end (elsewhere).     *     * iir_shift_bits effectively sets the number of samples used by     * the filter * (number of samples is 2^iir_shift_bits).     * Lower iir_width means less pointer lag, higher iir_width means     * steadier pointer.     */#ifndef _TP_HELIO    const int iir_shift_bits = 3;    const int iir_sample_depth = (1 << iir_shift_bits);#endif    static int iir_accum_x = 0;    static int iir_accum_y = 0;    static int iir_accum_z = 0;    static int iir_count = 0;    int data_x, data_y, data_z;    /* read a data point */#ifdef _TP_HELIO    short data[3];#else    short data[6];#endif    int bytes_read;    bytes_read = read(tp_fd, data, sizeof(data));    if (bytes_read != sizeof(data)) {        if (errno == EINTR || errno == EAGAIN) {            return 0;        }        return -1;    }#ifdef _TP_TSBREF    if(data[0]&0x8000) {        *px = data[2] - data[1];        *py = data[4] - data[3];        *pz = 0;        *pb = BUTTON_L;        return 2;    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -