/*******************************************************************************
*                                                                              *
*                                   Viewmol                                    *
*                                                                              *
*                               D E V I C E . C                                *
*                                                                              *
*                 Copyright (c) Joerg-R. Hill, October 2003                    *
*                                                                              *
********************************************************************************
*
* $Id: device.c,v 1.4 2003/11/07 10:59:19 jrh Exp $
* $Log: device.c,v $
* Revision 1.4  2003/11/07 10:59:19  jrh
* Release 2.4
*
* Revision 1.3  2000/12/10 15:04:26  jrh
* Release 2.3
*
* Revision 1.2  1999/05/24 01:25:04  jrh
* Release 2.2.1
*
* Revision 1.1  1999/02/07 21:46:29  jrh
* Initial revision
*
*
*/
#include<stdio.h>
#include<stdlib.h>
#include<X11/Intrinsic.h>
#include<X11/Xlib.h>
#include<X11/extensions/XInput.h>

#define MAXLENLINE 80

void findInputDevices(Widget);

extern Widget topShell;
extern int debug;
extern int spaceballButtonPress, spaceballMotionNotify;

static XDevice *spaceball;
static struct {int min;
               float range;} axis[6];

void findInputDevices(Widget w)
{
  Display *display;
  XExtensionVersion *version;
  XDeviceInfo *list;
  XAnyClassPtr classinfo;
  XValuatorInfoPtr info;
  XAxisInfoPtr a;
  XEventClass eventList[2];
  int ndev;
  register int i, j, k;

  display=XtDisplay(topShell);
  version=XGetExtensionVersion(display, "XInputExtension");
  if (version == NULL || ((int)version) == NoSuchExtension) return;
  XFree(version);   
  list=XListInputDevices(display, &ndev);
  for (i=0; i<ndev; i++)
  {
    if (!strcmp(list[i].name, XI_SPACEBALL) || !strcmp(list[i].name, "SpaceOrb"))
    {
      if (debug) printf("Found spaceball.\n");
      classinfo=list[i].inputclassinfo;
      for (j=0; j<list[i].num_classes; j++)
      {
        switch (classinfo->class)
        {
          case ValuatorClass: info=(XValuatorInfoPtr)classinfo;
                              if (info->num_axes < 6) goto nextDevice;
                              a=(XAxisInfoPtr)((char *)info+sizeof(XValuatorInfo));
                              for (k=0; k<6; k++)
                              {
                                axis[k].min=a->min_value;
                                axis[k].range=2.0/(float)(a->max_value-a->min_value);
                              }
                              break;
        }
        classinfo=(XAnyClassPtr)((char *)classinfo+classinfo->length);
      }
      spaceball=XOpenDevice(display, list[i].id);
      DeviceButtonPress(spaceball, spaceballButtonPress, eventList[0]);
      DeviceMotionNotify(spaceball, spaceballMotionNotify, eventList[1]);
      XSelectExtensionEvent(display, XtWindow(w), eventList, 2);
      break;
    }
    nextDevice:;
  }
  XFreeDeviceList(list);
}

void switchPointerDevice(void)
{
  FILE *file;
  char line[MAXLENLINE], command[MAXLENLINE];

  if ((file=popen("xsetpointer -l", "r")) != NULL)
  {
    while (fgets(line, MAXLENLINE, file) != NULL)
    {
      if (strstr(line, "XExtensionDevice"))
      {
        strcpy(command, "xsetpointer ");
        strcat(command, strtok(line, " \t"));
        system(command);
      }
    }
    fclose(file);
  }
}
