[t:/]$ 지식_

DiretFB tslib - linux-input built-in.

2009/01/21

이로서 지터보정 및 리니어 보정이 linux-input 안에 통째로 붙었다.

jitter 보정은 커서 흔들림을 잡는 것이다. linear 보정은 캘리브레이션 정보에 근거하여 실측값을 뽑는다.

코드를 짤 때 주의사항은 adc 날값(=거대값)으로 지터를 잡아야 한다. 해상도에 맞게 보정된 값으로 지터를 잡으면 커서가 그리드 스냅에 걸린 것 처럼 움직일 것이다.

아래 코드에서 상수 2500은 adc에서 얻어오는 bit수에 따라 적절히 경험적 가감으로 정한다.

static void *linux_input_EventThread( DirectThread *thread, void *driver_data)
{
    LinuxInputData    *data = (LinuxInputData*) driver_data;
    int                readlen, status;
    unsigned int       i;
    struct input_event levt[64];            // 실제 저장
    fd_set             set;
     
    int temp_x, temp_y;
    int prevx, prevy;
    int dr2;
 
      
    DFBInputEvent devt = { type: DIET_UNKNOWN, flags: DIEF_NONE };

    
    while (1) {
          
          
//          direct_thread_testcancel( thread );
        readlen = read( data->fd, levt, sizeof(levt) );
           if (readlen < 0 && errno != EINTR)
            break;

//        direct_thread_testcancel( thread );

        if (readlen <= 0)
            continue;

        for (i = 0; i < readlen / sizeof(levt[0]); i++) {
            DFBInputEvent temp;
            
            if (levt[i].value) {
                switch(levt[i].code) {
                    case ABS_X:
            
                        // 지터 보정
                        dr2 = (prevx - levt[i].value) * (prevx - levt[i].value);
                        if (dr2 < 2500) 
                            levt[i].value = prevx;
                        else 
                            prevx = levt[i].value;            
                            
                        // 리니어 보정
                        temp_x = levt[i].value;
                        levt[i].value = ( lin.a[2] +
                                        lin.a[0]*temp_x + 
                                        lin.a[1]*temp_y ) / lin.a[6];
                                                                    
                        
                        break;
                            
                    case ABS_Y:
                        
                        dr2 = (prevy - levt[i].value) * (prevy - levt[i].value);
                        if (dr2 < 2500) 
                            levt[i].value = prevy;                    
                        else 
                            prevy = levt[i].value;            
                            
                        temp_y = levt[i].value;
                        levt[i].value = ( lin.a[5] +
                                        lin.a[3]*temp_x +
                                        lin.a[4]*temp_y ) / lin.a[6];                            
                            
                        break;
                            
                    default:
                        break;
                }
            }
            
            if (!translate_event( &levt[i], &temp )) {
            // 눌림 시작과 끝에선 여기
                continue;
            }
            
            // 계속이면.                   
            
            /* Flush previous event with DIEF_FOLLOW? */
            if (devt.type != DIET_UNKNOWN) {
                /* Signal immediately following event. */
                devt.flags |= DIEF_FOLLOW;
                dfb_input_dispatch( data->device, &devt );

                devt.type  = DIET_UNKNOWN;
                devt.flags = DIEF_NONE;
            }
               
            devt = temp;
               
        }

        /* Flush last event without DIEF_FOLLOW. */
        if (devt.type != DIET_UNKNOWN) {
            dfb_input_dispatch( data->device, &devt );
        }
    }

    if (status <= 0)
        D_PERROR ("linux_input thread died\n");

    return NULL;
}








[t:/] is not "technology - root". dawnsea, rss