--- /dev/null
+/* test driver to make sure i can do things... */
+
+/* _X_EXPORT defined in /usr/local/include/X11/Xfuncproto.h,
+ included by /usr/local/include/xorg/xf86.h */
+#include <xorg/xf86.h>
+
+/* so the version macros exist */
+#include <xorg/xorg-server.h>
+
+/* XF86ModuleData is defined in /usr/local/include/xorg/xf86Module.h */
+/* #include <xorg/xf86Module.h> */
+/* NOTE: this is done by xf86Xinput.h */
+#include <xorg/xf86Xinput.h>
+
+#include <xorg/xserver-properties.h>
+#include <xorg/exevents.h>
+
+#include <errno.h>
+#include <fcntl.h> /* open, creat */
+#include <unistd.h> /* close */
+#include <linux/input.h>
+
+enum codes {
+ TP_STICK_HORI = 0,
+ TP_STICK_VERT = 1,
+ TP_LEFT = 272,
+ TP_RIGHT = 273,
+ TP_MIDDLE = 274,
+};
+
+enum type {
+ TP_NOP = 0,
+ TP_BUTTON = 1,
+ TP_STICK = 2,
+};
+
+enum button {
+ TP_BUTTON_UP = 0,
+ TP_BUTTON_DOWN = 1,
+};
+
+struct tlb_device_private_data {
+ int fd;
+ ValuatorMask *valuators;
+ unsigned char btnmap[4]; /* left/right/middle */
+};
+
+/* lifted from libinput */
+static void tlb_ptr_ctl(DeviceIntPtr dev, PtrCtrl *ctl)
+{
+ InputInfoPtr pInfo = dev->public.devicePrivate;
+ xf86IDrvMsg(pInfo, X_ERROR, "tlb_ptr_ctl NOT IMPLEMENTED\n");
+}
+
+static int tlb_device_init(DeviceIntPtr dev)
+{
+ InputInfoPtr pInfo = dev->public.devicePrivate;
+ xf86IDrvMsg(pInfo, X_INFO, "tlb_device_control (DEVICE_INIT) \n");
+
+ struct tlb_device_private_data *priv = pInfo->private;
+ char *device = xf86CheckStrOption(pInfo->options, "Device", NULL);
+ xf86IDrvMsg(pInfo, X_INFO, "attempting to open device '%s'.\n", device);
+
+ priv->fd = open(device, O_RDONLY);
+ if(-1 == priv->fd){
+ xf86IDrvMsg(pInfo, X_ERROR, "FAILED TO OPEN '%s'. (errno=%d).\n", device, errno);
+ return BadValue;
+ }
+
+ xf86IDrvMsg(pInfo, X_INFO, "Opened '%s' successfully.\n", device);
+
+ /* lifted from libinput driver */
+ Atom btnlabels[3];
+ btnlabels[0] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_LEFT);
+ btnlabels[1] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_MIDDLE);
+ btnlabels[2] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_RIGHT);
+
+ Atom axislabels[2];
+ axislabels[0] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_X);
+ axislabels[1] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_Y);
+ /* labels[2] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_HSCROLL); */
+ /* labels[3] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_VSCROLL); */
+
+ priv->btnmap[1] = 1;
+ priv->btnmap[2] = 2;
+ priv->btnmap[3] = 3;
+ InitPointerDeviceStruct((DevicePtr)dev,
+ priv->btnmap,
+ 3,
+ btnlabels,
+ tlb_ptr_ctl, /* why can't be null */
+ GetMotionHistorySize(), /* ??? */
+ 2,
+ axislabels);
+
+ /* ???? */
+ int min, max, res;
+ min = -1;
+ max = -1;
+ res = 0;
+
+ xf86InitValuatorAxisStruct(dev, 0,
+ XIGetKnownProperty(AXIS_LABEL_PROP_REL_X),
+ min, max, res * 1000, 0, res * 1000, Relative);
+ xf86InitValuatorDefaults(dev, 0);
+ xf86InitValuatorAxisStruct(dev, 1,
+ XIGetKnownProperty(AXIS_LABEL_PROP_REL_Y),
+ -1, -1, 1, 0, 1, Relative);
+ xf86InitValuatorDefaults(dev, 1);
+
+ /* TODO */
+ /* axis def??? x,y,vscroll,hscroll */
+ return Success;
+}
+
+static int tlb_device_on(DeviceIntPtr dev)
+{
+ InputInfoPtr pInfo = dev->public.devicePrivate;
+ xf86IDrvMsg(pInfo, X_INFO, "tlb_device_control (DEVICE_ON) Partially implemented\n");
+
+ /* start up pthread polling or something? */
+ struct tlb_device_private_data *priv = pInfo->private;
+ pInfo->fd = priv->fd;
+ xf86AddEnabledDevice(pInfo);
+
+ /* TODO: implement */
+ return Success;
+}
+
+static int tlb_device_off(DeviceIntPtr dev)
+{
+ InputInfoPtr pInfo = dev->public.devicePrivate;
+ xf86IDrvMsg(pInfo, X_INFO, "tlb_device_control (DEVICE_OFF) Partially implemented\n");
+
+ /* shutdown polling pthread or something? */
+ xf86RemoveEnabledDevice(pInfo);
+
+ /* TODO: implement */
+ return Success;
+}
+
+static int tlb_device_close(DeviceIntPtr dev)
+{
+ InputInfoPtr pInfo = dev->public.devicePrivate;
+ xf86IDrvMsg(pInfo, X_INFO, "tlb_device_control (DEVICE_CLOSE) Partially implemented\n");
+
+ struct tlb_device_private_data *priv = pInfo->private;
+ char *device = xf86CheckStrOption(pInfo->options, "Device", NULL);
+
+ if(-1 != priv->fd){
+ if(-1 == close(priv->fd)){
+ xf86IDrvMsg(pInfo, X_ERROR, "FAILED TO CLOSE '%s'. (errno=%d).\n", device, errno);
+ return BadValue;
+ }
+
+ priv->fd = -1;
+ xf86IDrvMsg(pInfo, X_INFO, "Closed '%s' successfully.\n", device);
+ }
+
+ return Success;
+}
+
+static int tlb_device_abort(DeviceIntPtr dev)
+{
+ InputInfoPtr pInfo = dev->public.devicePrivate;
+ xf86IDrvMsg(pInfo, X_ERROR, "tlb_device_control (DEVICE_ABORT) NOT IMPLEMENTED\n");
+ return BadValue;
+}
+
+static int tlb_device_control(DeviceIntPtr dev, int mode)
+{
+ int retval = BadValue;
+ /* TODO: implement */
+ switch(mode){
+ /* defined in /usr/local/include/xorg/input.h */
+ case DEVICE_INIT:
+ retval = tlb_device_init(dev);
+ break;
+ case DEVICE_ON:
+ retval = tlb_device_on(dev);
+ break;
+ case DEVICE_OFF:
+ retval = tlb_device_off(dev);
+ break;
+ case DEVICE_CLOSE:
+ retval = tlb_device_close(dev);
+ break;
+ case DEVICE_ABORT:
+ retval = tlb_device_abort(dev);
+ break;
+ };
+ return retval;
+}
+
+static void tlb_read_input(InputInfoPtr pInfo)
+{
+ /* TODO: implement */
+ /* xf86IDrvMsg(pInfo, X_ERROR, "tlb_read_input NOT IMPLEMENTED\n"); */
+ DeviceIntPtr dev = pInfo->dev;
+ struct tlb_device_private_data *priv = pInfo->private;
+
+ /* 48, 72 bytes. seems like 100 is fine. */
+#define BUF_SIZ 1000
+ static unsigned char buf[BUF_SIZ] = {};
+ ssize_t cnt = 0;
+ /* do one at a time, xorg server will call use when we have more events */
+ if(0 < (cnt = read(pInfo->fd, buf, BUF_SIZ))){
+ /* we are _always_ supposed to get a whole number of events on a read. */
+ unsigned char *cur = buf;
+ int x = 0, y = 0;
+ char hasx = 0, hasy = 0;
+ while(cnt != 0){
+ char isx = 0, isy = 0;
+ struct input_event *ev = (struct input_event *)cur;
+ cnt -= sizeof(struct input_event);
+ cur += sizeof(struct input_event);
+
+ /* dump the event we got i guess */
+ char *code_str, *type_str, *button_str;
+ switch(ev->type){
+ case TP_BUTTON: { code_str = " BUTT"; break; }
+ case TP_STICK: { code_str = "STICK"; break; }
+ case TP_NOP:
+ default:{
+ /* skip entirely */
+ continue; /* while loop */
+ }
+ }
+
+ switch(ev->code){
+ case TP_STICK_HORI:{
+ hasx = 1;
+ isx = 1;
+ if(ev->value > 0)
+ type_str = "RIGHT";
+ else
+ type_str = " LEFT";
+ break;
+ }
+ case TP_STICK_VERT:{
+ hasy = 1;
+ isy = 1;
+ if(ev->value > 0)
+ type_str = " DOWN";
+ else
+ type_str = " UP";
+ break;
+ }
+ case TP_LEFT: {
+ type_str = " LEFT";
+ xf86PostButtonEvent(dev, 0, 1, ev->value, 0, 0);
+ break;
+ }
+ case TP_RIGHT: {
+ type_str = "RIGHT";
+ xf86PostButtonEvent(dev, 0, 3, ev->value, 0, 0);
+ break;
+ }
+ case TP_MIDDLE:{
+ type_str = " MID";
+ xf86PostButtonEvent(dev, 0, 2, ev->value, 0, 0);
+ break;
+ }
+ }
+
+ char output_msg[200];
+
+ int offset = sprintf(output_msg,
+ "%d.%09d: %s %s ",
+ ev->input_event_sec, ev->input_event_usec,
+ type_str, code_str);
+
+ if(ev->type == TP_BUTTON){
+ switch(ev->value){
+ case TP_BUTTON_UP: { sprintf(output_msg + offset, " UP\n"); break; }
+ case TP_BUTTON_DOWN:{ sprintf(output_msg + offset, "DOWN\n"); break; }
+ }
+ }else{
+ sprintf(output_msg + offset, "%d\n", ev->value);
+ if(isx){
+ x = ev->value;
+ }
+ if(isy){
+ y = ev->value;
+ }
+ }
+
+ xf86IDrvMsg(pInfo, X_INFO, output_msg);
+ }
+
+ ValuatorMask *mask = priv->valuators;
+ valuator_mask_zero(mask);
+
+ if(hasx){
+ valuator_mask_set_double(mask, 0, x);
+ }
+ if(hasy){
+ valuator_mask_set_double(mask, 1, y);
+ }
+ if(hasx || hasy){
+ /* xf86PostMotionEventM(dev, Relative, mask); */
+ /* xf86IDrvMsg(pInfo, X_INFO, "Posting motion with x=%d, y=%d\n"); */
+ xf86PostMotionEvent(dev, 0, 0, 2, x, y);
+ }
+ }
+}
+
+static int tlb_pre_init(InputDriverPtr drv, InputInfoPtr pInfo, int flags)
+{
+ /* TODO: have to __actually__ make a driver, it turns out */
+ pInfo->type_name = 0;
+ pInfo->device_control = tlb_device_control;
+ pInfo->read_input = tlb_read_input;
+ pInfo->control_proc = NULL;
+ pInfo->switch_mode = NULL;
+
+ /* my own data i guess */
+ pInfo->private = malloc(sizeof(struct tlb_device_private_data));
+ ((struct tlb_device_private_data *)pInfo->private)->fd = -1;
+ ((struct tlb_device_private_data *)pInfo->private)->valuators = valuator_mask_new(6);
+
+ /* TODO: init driver data... i guess */
+
+ xf86IDrvMsg(pInfo, X_INFO, "init for driver 'tlb' SUCCEEDED.\n");
+
+ pInfo->type_name = XI_MOUSE;
+ return Success;
+}
+
+static void tlb_uninit(InputDriverPtr drv, InputInfoPtr pInfo, int flags)
+{
+ if(NULL != pInfo->private){
+ /* this seg faults it seems.... */
+ /* free(pInfo->private); */
+ valuator_mask_free(&((struct tlb_device_private_data *)pInfo->private)->valuators);
+ }
+
+ /* TODO: things */
+ xf86DeleteInput(pInfo, flags);
+}
+
+InputDriverRec tlb_driver = {
+ .driverVersion = 1,
+ .driverName = "tlb",
+ .PreInit = tlb_pre_init,
+ .UnInit = tlb_uninit,
+ .module = NULL,
+ .default_options = NULL,
+};
+
+static pointer tlb_setup_proc(pointer module, pointer options, int *errmaj, int *errmin)
+{
+ xf86AddInputDriver(&tlb_driver, module, 0);
+ return module;
+}
+
+/* This structure is expected to be returned by the initfunc */
+static XF86ModuleVersionInfo tlb_mod_version = {
+ .modname = "tlb-track", /* name of module, e.g. "foo" */
+ .vendor = MODULEVENDORSTRING, /* vendor specific string */
+ ._modinfo1_ = MODINFOSTRING1, /* constant MODINFOSTRING1/2 to find */
+ ._modinfo2_ = MODINFOSTRING2, /* infoarea with a binary editor or sign tool */
+ .xf86version = XORG_VERSION_CURRENT,
+ .majorversion = 0, /* module-specific major version */
+ .minorversion = 0, /* module-specific minor version */
+ .patchlevel = 2, /* module-specific patch level */
+ .abiclass = ABI_CLASS_XINPUT, /* ABI class that the module uses */
+ .abiversion =ABI_XINPUT_VERSION, /* ABI version */
+ .moduleclass = MOD_CLASS_XINPUT, /* module class description */
+ .checksum = { 0, 0, 0, 0 }, /* contains a digital signature of the */
+};
+
+_X_EXPORT XF86ModuleData tlbModuleData = {
+ .vers = &tlb_mod_version,
+ .setup = tlb_setup_proc,
+ .teardown = NULL,
+};