本文主要是介绍关于directfb,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
http://www.doc88.com/p-116663997270.html
具体内容以后补上,上面是参考网址
分析一下directfb的输入驱动调用流程吧,
使用directfb时,系统会从目录寻找对应子系统的.so库,然后加载库到系统中,具体过程我也没细看,上面那个网址里的介绍非常详细,
以其中的linuxinput为例,看看过程,direcfb的linuxinput 驱动
加载了linuxinput模块后,
/** Return the number of available devices.* Called once during initialization of DirectFB.*/
static int
driver_get_available( void )
{int i;char *tsdev;#ifdef LINUX_INPUT_USE_FBDEVif (dfb_system_type() != CORE_FBDEV)return 0;
#endif/* Use the devices specified in the configuration. */if (fusion_vector_has_elements( &dfb_config->linux_input_devices )) {const char *device;fusion_vector_foreach (device, i, dfb_config->linux_input_devices) {if (num_devices >= MAX_LINUX_INPUT_DEVICES)break;if (check_device( device ))device_names[num_devices++] = D_STRDUP( device );}return num_devices;}/* Check for tslib device being used. */tsdev = getenv( "TSLIB_TSDEVICE" );/* No devices specified. Try to guess some. */for (i=0; i<MAX_LINUX_INPUT_DEVICES; i++) {char buf[32];snprintf( buf, 32, "/dev/input/event%d", i );/* Let tslib driver handle its device. */if (tsdev && !strcmp( tsdev, buf ))continue;if (check_device( buf ))device_names[num_devices++] = D_STRDUP( buf );}return num_devices;
}
初始化时首先要调用driver_get_available( void )查找设备的数目,这里面主要用到了check_device()函数
static bool
check_device( const char *device )
{int fd;/* Check if we are able to open the device */fd = open( device, O_RDWR );if (fd < 0) {return false;}else {InputDeviceInfo info;bool touchpad;/* try to grab the device */if (dfb_config->linux_input_grab) {/* 2.4 kernels don't have EVIOCGRAB so ignore EINVAL */if (ioctl( fd, EVIOCGRAB, 1 ) && errno != EINVAL) {close( fd );return false;}}memset( &info, 0, sizeof(InputDeviceInfo) );get_device_info( fd, &info, &touchpad );if (dfb_config->linux_input_grab)ioctl( fd, EVIOCGRAB, 0 );close( fd );if (!dfb_config->linux_input_ir_only ||(info.desc.type & DIDTF_REMOTE))return true;}return false;
}
检测完设备后,就执行driver_open_device()函数,这个函数的作用主要是打开设备,封装原来的设备信息,然后开启输入线程,当外部有输入时执行线程处理函数,,然后把输入信息上报到上层,从而实现时间响应,我也只是猜测,但是大体上应该就差不多这么个过程
/** Open the device, fill out information about it,* allocate and fill private data, start input thread.* Called during initialization, resuming or taking over mastership.*/
static DFBResult
driver_open_device( CoreInputDevice *device,unsigned int number,InputDeviceInfo *info,void **driver_data )
{int fd, ret;unsigned long ledbit[NBITS(LED_CNT)];LinuxInputData *data;
#ifdef LINUX_INPUT_USE_FBDEVFBDev *dfb_fbdev = dfb_system_data();
#endifbool touchpad;/* open device */fd = open( device_names[number], O_RDWR );if (fd < 0) {D_PERROR( "DirectFB/linux_input: could not open device" );return DFB_INIT;}/* grab device */if (dfb_config->linux_input_grab) {ret = ioctl( fd, EVIOCGRAB, 1 );/* 2.4 kernels don't have EVIOCGRAB so ignore EINVAL */if (ret && errno != EINVAL) {D_PERROR( "Direc tFB/linux_input: could not grab device" );close( fd );return DFB_INIT;}}/* fill device info structure */get_device_info( fd, info, &touchpad );/* allocate and fill private data */data = D_CALLOC( 1, sizeof(LinuxInputData) );if (!data) {if (dfb_config->linux_input_grab)ioctl( fd, EVIOCGRAB, 0 );close( fd );return D_OOM();}data->fd = fd;data->device = device;
#ifdef LINUX_INPUT_USE_FBDEVdata->vt = dfb_fbdev->vt;
#endifdata->touchpad = touchpad;/* check if the device has LEDs */ret = ioctl( fd, EVIOCGBIT(EV_LED, sizeof(ledbit)), ledbit );if (ret < 0)D_PERROR( "DirectFB/linux_input: could not get LED bits" );elsedata->has_leds = test_bit( LED_SCROLLL, ledbit ) ||test_bit( LED_NUML, ledbit ) ||test_bit( LED_CAPSL, ledbit );if (data->has_leds) {/* get LED state */ret = ioctl( fd, EVIOCGLED(sizeof(data->led_state)), data->led_state );if (ret < 0) {D_PERROR( "DirectFB/linux_input: could not get LED state" );if (dfb_config->linux_input_grab)ioctl( fd, EVIOCGRAB, 0 );close( fd );D_FREE( data );return DFB_INIT;}/* turn off LEDs */set_led( data, LED_SCROLLL, 0 );set_led( data, LED_NUML, 0 );set_led( data, LED_CAPSL, 0 );}/* start input thread */data->thread = direct_thread_create( DTT_INPUT, linux_input_EventThread, data, "Linux Input" );/* set private data pointer */*driver_data = data;return DFB_OK;
}
然后在directfb输入驱动中很关键的一个函数是
/** Input thread reading from device.* Generates events on incoming data.*/
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;struct touchpad_fsm_state fsm_state;/* Query min/max coordinates. */if (data->touchpad) {struct input_absinfo absinfo;touchpad_fsm_init( &fsm_state );ioctl( data->fd, EVIOCGABS(ABS_X), &absinfo );fsm_state.x.min = absinfo.minimum;fsm_state.x.max = absinfo.maximum;ioctl( data->fd, EVIOCGABS(ABS_Y), &absinfo );fsm_state.y.min = absinfo.minimum;fsm_state.y.max = absinfo.maximum;}while (1) {DFBInputEvent devt = { .type = DIET_UNKNOWN };FD_ZERO( &set );FD_SET( data->fd, &set );if (data->touchpad && timeout_is_set( &fsm_state.timeout )) {struct timeval time;gettimeofday( &time, NULL );if (!timeout_passed( &fsm_state.timeout, &time )) {struct timeval timeout = fsm_state.timeout;timeout_sub( &timeout, &time );status = select( data->fd + 1, &set, NULL, NULL, &timeout );} else {status = 0;}}else {status = select( data->fd + 1, &set, NULL, NULL, NULL );}if (status < 0 && errno != EINTR)break;direct_thread_testcancel( thread );if (status < 0)continue;/* timeout? */if (status == 0) {if (data->touchpad && touchpad_fsm( &fsm_state, NULL, &devt ) > 0)dfb_input_dispatch( data->device, &devt );continue;}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 = { .type = DIET_UNKNOWN };if (data->touchpad) {status = touchpad_fsm( &fsm_state, &levt[i], &temp );if (status < 0) {/* Not handled. Try the direct approach. */if (!translate_event( &levt[i], &temp ))continue;}else if (status == 0) {/* Handled but no further processing is necessary. */continue;}}else {if (!translate_event( &levt[i], &temp ))continue;}/* Flush previous event with DIEF_FOLLOW? */if (devt.type != DIET_UNKNOWN) {flush_xy( data, false );/* Signal immediately following event. */devt.flags |= DIEF_FOLLOW;dfb_input_dispatch( data->device, &devt );if (data->has_leds && (devt.locks != data->locks)) {set_led( data, LED_SCROLLL, devt.locks & DILS_SCROLL );set_led( data, LED_NUML, devt.locks & DILS_NUM );set_led( data, LED_CAPSL, devt.locks & DILS_CAPS );data->locks = devt.locks;}devt.type = DIET_UNKNOWN;devt.flags = DIEF_NONE;}devt = temp;if (D_FLAGS_IS_SET( devt.flags, DIEF_AXISREL ) && devt.type == DIET_AXISMOTION &&dfb_config->mouse_motion_compression){switch (devt.axis) {case DIAI_X:data->dx += devt.axisrel;continue;case DIAI_Y:data->dy += devt.axisrel;continue;default:break;}}/* Event is dispatched in next round of loop. */}/* Flush last event without DIEF_FOLLOW. */if (devt.type != DIET_UNKNOWN) {flush_xy( data, false );dfb_input_dispatch( data->device, &devt );if (data->has_leds && (devt.locks != data->locks)) {set_led( data, LED_SCROLLL, devt.locks & DILS_SCROLL );set_led( data, LED_NUML, devt.locks & DILS_NUM );set_led( data, LED_CAPSL, devt.locks & DILS_CAPS );data->locks = devt.locks;}}elseflush_xy( data, true );}if (status <= 0)D_PERROR ("linux_input thread died\n");return NULL;
}
这个函数对我们添加directfb输入时间支持很关键啊,这几天我在让directfb支持我的tiny210的触摸屏,,隔几天接着写吧
这篇关于关于directfb的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!