Provide initialization and cleanup callback functions
Screen makes two function calls in the driver: one for initialization and one for cleanup.
Screen parses the configuration file,
graphics.conf, to determine the driver specified in the
mtouch
section of this configuration file.
Screen calls dlopen() on this specified driver. Upon a successful dlopen(), Screen will use dlsym() to look for two entries: mtouch_driver_init() and mtouch_driver_fini().
Implement initialization callback function
mtouch_driver_init() performs the following:
- Sets the default values of the driver.
- Parses any options specified in graphics.conf
using input_parseopts(). For details, see the
Touch configuration file
section in the Screen documentation. - Performs any necessary hardware initialization.
- Configure callback functions using
mtouch_driver_funcs_t
as described in Connect to the Input Events library. - Specify driver parameters using
mtouch_driver_params_t
as described in Connect to the Input Events library. - Connect to Input Events library as described in Connect to the Input Events library.
- Create a separate thread to communicate directly with the hardware via the hardware interface (e.g., I2C, SPI, USB, etc.) and trigger the Input Events library API function mtouch_driver_process_packet() to start processing the touch-related event data.
void* (*init)(const char* options);
An example implementation of mtouch_driver_init():
void * mtouch_driver_init(const char* options)
{
pthread_attr_t pattr;
sched_param_t param;
/* touch_dev_t is the structure which contains information specific to
* your touch device along with other NTO and thread information.
*/
touch_dev_t *td = (touch_dev_t *)calloc(1,sizeof(touch_dev_t));
memset(td,0,sizeof(touch_dev_t));
if(td==NULL){
mtouch_error("touch_device", "Failed to allocate memory for device structure");
return NULL;
}
/* Initialize any defaults for your touch device here */
td->thread_priority = 21; /* Thread priority for communicating directly with the hardware */
/* Parse the mtouch options from graphics.conf */
input_parseopts(options, set_options, td);
/* Connect to device */
td->chid = ChannelCreate(0);
if(td->chid == -1) {
mtouch_error("touch_device","%s: ChannelCreate: %s",__FUNCTION__,strerror(errno));
goto failChannelCreate;
}
td->coid = ConnectAttach(0,0,td->chid,_NTO_SIDE_CHANNEL,0);
if(td->coid==-1) {
mtouch_error("touch_device","%s: ConnectAttach: %s",__FUNCTION__,strerror(errno));
goto failConnectAttach;
}
/* Utility function attach_drier() to configure your callback function and
* connect to the Input Events library
*/
if(attach_driver(td)!=EOK) {
goto failAttachLibInputEvents;
}
pthread_attr_init(&pattr);
param.sched_priority = td->thread_priority;
pthread_attr_setschedparam(&pattr, ¶m);
pthread_attr_setinheritsched(&pattr, PTHREAD_EXPLICIT_SCHED);
/* Create a thread for communicating directly with the hardware and to
* trigger mtouch_driver_process_packet() */
int ret = pthread_create(&td->recv_thread, &pattr, tp_recv_thread, td);
if (EOK != ret) {
mtouch_error("touch_device", "Failed to create the intr thread (%s - %i)",strerror(errno),ret);
goto failCreateThread;
}
pthread_setname_np(td->recv_thread, "touch_device");
return td;
failCreateThread:
InterruptDetach(td->tp_iid);
td->tp_iid = -1;
failAttachLibInputEvents:
mtouch_driver_detach(td->inputevents_hdl);
td->inputevents_hdl = NULL;
failInitialize:
ChannelDestroy(td->chid);
td->chid = -1;
failConnectAttach:
ConnectDetach(td->chid);
td->chid = -1;
failChannelCreate:
free(td);
return NULL;
}
Implement cleanup callback function
mtouch_driver_fini() performs any necessary device cleanup and disconnects from the Input Events library.
void (*fini)(void* dev);
An example implementation of mtouch_driver_fini():
void mtouch_driver_fini(void* dev)
{
touch_dev_t *td = dev;
pthread_cancel(td->tp_recv_thread);
pthread_join(td->tp_recv_thread, NULL);
if (td->inputevents_hdl) {
mtouch_driver_detach(td->inputevents_hdl);
td->inputevents_hdl = NULL;
}
free(td);
}