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:

  1. Sets the default values of the driver.
  2. Parses any options specified in graphics.conf using input_parseopts(). See Touch configuration file.
  3. Performs any necessary hardware initialization.
  4. Configure callback functions using mtouch_driver_funcs_t as described in Connect to the Input Events library.
  5. Specify driver parameters using mtouch_driver_params_t as described in Connect to the Input Events library.
  6. Connect to Input Events library as described in Connect to the Input Events library.
  7. 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.
The driver insertion point for Screen is mtouch_driver_init(). This callback function has the following signature:
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, &param);
	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.

The driver exit point for Screen is mtouch_driver_fini(). This callback function has the following signature:
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);
}