ftp.nice.ch/pub/next/unix/admin/evs.1.0.NIHS.s.tar.gz#/evs/evs.c

This is evs.c in view mode; [Download] [Up]

/*
 * evsinfo.c -- get some information from the event system
 *
 * $Header: /Users/marcel/src/evs/RCS/evs.c,v 1.5 1996/01/31 12:35:51 marcel Exp mwa $
 *
 * (c) 1996 Marcel Waldvogel, mwa@nice.ch
 *
 * History
 * =======
 * 960122 mwa	Created
 * 960131 mwa	Added support for NS 3.2
 */

#import <drivers/event_status_driver.h>
#import <stdlib.h>
#import <stddef.h>
#import <stdarg.h>
#import <string.h>
#import <defaults/defaults.h>
#import <objc/objc.h>
#import <sys/types.h>
#import <sys/dir.h>

typedef const struct {
  int	id;
  char  *name;
} NAMES;

typedef struct _kbd {
  int	interface;
  int	id;
  char	*name;
  struct _kbd *next;
} KBD;

// Define some widths for the output columns
#define BUSW "16"
#define DEVW "7"
#define TYPW "9"
#define ID_W "10"

// The extension of keyboard description files
#define KBDEXT ".keyboard"

// Length of the line buffer
#define LBLEN 1024

NAMES bus[] = {
  { NX_EVS_DEVICE_INTERFACE_OTHER,	"Other"},
  { NX_EVS_DEVICE_INTERFACE_NeXT,	"NeXT (NDB)"},
  { NX_EVS_DEVICE_INTERFACE_ADB, 	"ADB"},
  { NX_EVS_DEVICE_INTERFACE_ACE,	"PC ACE (kbd)"},
  { NX_EVS_DEVICE_INTERFACE_SERIAL_ACE,	"PC ACE (serial)"},
  { NX_EVS_DEVICE_INTERFACE_BUS_ACE,	"PC ACE (bus)"},
#ifdef NX_EVS_DEVICE_INTERFACE_HIL 
  { NX_EVS_DEVICE_INTERFACE_HIL,	"HP HIL"},
#endif
#ifdef NX_EVS_DEVICE_INTERFACE_TYPE5
  { NX_EVS_DEVICE_INTERFACE_TYPE5,	"Sun Type5"},
#endif
  { 0, NULL},
};

NAMES type[] = {
  { NX_EVS_DEVICE_TYPE_OTHER,		"Other"},
  { NX_EVS_DEVICE_TYPE_KEYBOARD, 	"Keyboard"},
  { NX_EVS_DEVICE_TYPE_MOUSE,		"Mouse"},
  { NX_EVS_DEVICE_TYPE_TABLET,		"Tablet"},
  { 0, NULL},
};

NAMES button[] = {
  { NX_OneButton,			"None"},
  { NX_LeftButton,			"Left"},
  { NX_RightButton,			"Right"},
  { 0, NULL},
};

NAMES bool[] = {
  { NO,					"NO"},
  { YES,				"YES"},
  { 0, NULL},
};

KBD *keyboards = NULL;

void usage(const char *prog)
{
  fprintf(stderr, "Usage: %s <command> [<args>]\n", prog);
  fputs(
"If no or too few args are given, the current settings are being displayed.\n"
"Commands: (can be abbreviated)\n"
"- list                          List of devices\n"
"- xlist                         Verbose list\n"
"- keyrepeat <thresh> <interval> Repeat threshold and interval\n"
"- click <time> <space>          Double click limits\n"
"- scaling <count> <args>        Mouse acceleration vector\n"
"- menu <menu button>            Menu button\n"
"- brightness <brightness>       Brightness\n"
"- idle                          Idle time, Time remaining to dim\n"
"- dim <delay> <brightness>      Dimming time, dim brightness\n"
"- Dimmed <dimming status>       Dimming status\n"
"- volume <volume>               Speaker volume\n"
"- wait <delay> <sustain>        Wait cursor delay and stay-up time\n"
"- Wait <framedelay>             Wait cursor animation speed\n"
"- all                           Show everything\n"
  , stderr); // End of fputs()
  exit(1);
}


void readkeyboards(const char *path)
{
  DIR *dir;
  struct direct *dp;
  FILE *k;
  char *fname;
  int pathlen, linelen;
  int mask;
  KBD *kbd;
  char linebuf[LBLEN];
  
  pathlen = strlen(path);
  dir = opendir(path);
  if (dir == NULL)
    return;
  while ((dp = readdir(dir)) != NULL)
  {
    // Does it end in .keyboard?
    if (dp->d_namlen > sizeof(KBDEXT)
        && strcmp(dp->d_name + dp->d_namlen - sizeof(KBDEXT) + 1, KBDEXT) == 0)
    {
      // We found a file, parse it!
      fname = malloc(pathlen + dp->d_namlen + sizeof("/"));
      strcpy(fname, path);
      strcat(fname, "/");
      strcat(fname, dp->d_name);
      k = fopen(fname, "r");
      if (k != NULL)
      {
        // We were able to! Great!
	// Allocate a new structure and connect it
	kbd = calloc(1, sizeof(KBD));
	kbd->next = keyboards;
	keyboards = kbd;
	mask = 0;
	while (mask != 7 && fgets(linebuf, LBLEN, k) != NULL)
	{
	  // Do we have a valid line?
	  linelen = strlen(linebuf);
	  if (linelen > 1 && linebuf[linelen - 1] == '\n')
	  {
	    linebuf[linelen - 1] = '\0';
	    linelen--;
	  }
	  else
	    continue;

	  // Check for the different keywords
	  if (strncmp(linebuf, "name ", sizeof("name")) == 0)
	  {
	    kbd->name = malloc(linelen - sizeof("name") + 1);
	    strcpy(kbd->name, linebuf + sizeof("name"));
	    mask |= 1;
	  }
	  if (strncmp(linebuf, "interface ", sizeof("interface")) == 0)
	  {
	    kbd->interface = atoi(linebuf + sizeof("interface"));
	    mask |= 2;
	  }
	  if (strncmp(linebuf, "handler_id ", sizeof("handler_id")) == 0)
	  {
	    kbd->id = atoi(linebuf + sizeof("handler_id"));
	    mask |= 4;
	  }
	}
        fclose(k);
      }
      free(fname);
    }
  }
  closedir(dir);
}

const char *kbdname(int interface, int id)
{
  KBD *kbd = keyboards;
  while (kbd != NULL)
  {
    // Did we find the right one?
    // (if the struct is filled incompletely, we may also get NULLs
    if (kbd->interface == interface && kbd->id == id && kbd->name != NULL)
      return kbd->name;
    kbd = kbd->next;
  }
  // Not found
  return NULL;
}

char *string(NAMES *names, unsigned int index)
{
  static char buf[20];

  // Is there anything reasonable out there?
  while (names->name != NULL)
  {
    if (names->id == index)
      return names->name;
    names++;
  }
  
  // No, make default
  sprintf(buf, "Unknown (%d)", index);
  return buf;
}

void evsinfo(NXEventHandle evs, BOOL verbose)
{
  NXEventSystemInfoType info;
  NXEventSystemDevice devs[NX_EVS_DEVICE_INFO_COUNT];
  unsigned int count, i;
  const char *name;

  // Get the information
  count = NX_EVS_DEVICE_INFO_COUNT;
  info = NXEventSystemInfo(evs, NX_EVS_DEVICE_INFO, (int *)devs, &count);
  count /= 4;

  printf("%-" BUSW "s%-" DEVW "s%-" TYPW "s%-" ID_W "s",
         "Bus", "Device", "Type", "ID");
  if (verbose)
  {
    printf("Name");
    // readkeyboards() adds the keyboards in reverse order found
    readkeyboards("/NextLibrary/Keyboards");
    // They aren't really being used by NS (at least not currently...)
    readkeyboards("/LocalLibrary/Keyboards");
  }
  putchar('\n');
  for (i = 0; i < count; i++)
  {
    printf("%-" BUSW "s", string(bus, devs[i].interface));
    printf("%-" DEVW "d", devs[i].interface_addr);
    printf("%-" TYPW "s", string(type, devs[i].dev_type));
    printf("%-" ID_W "u", devs[i].id);
    if (verbose && devs[i].dev_type == NX_EVS_DEVICE_TYPE_KEYBOARD)
    {
      name = kbdname(devs[i].interface, devs[i].id);
      if (name != NULL)
        printf("%s", name);
    }
    putchar('\n');
  }
}

BOOL atob(const char *s)
{
  switch (s[0])
  {
  case '0':
  case 'n':
  case 'N':
  case 'f':
  case 'F':
  default:		// Could be anywhere
    return NO;
  case '1':
  case 'y':
  case 'Y':
  case 't':
  case 'T':
    return YES;
  }
}

NXMouseButton atom(const char *s)
{
  switch (s[0])
  {
  case 'N':
  case 'n':
    return NX_OneButton;
  case 'L':
  case 'l':
    return NX_LeftButton;
  case 'R':
  case 'r':
    return NX_RightButton;
  default:
    return atoi(s);
  }
}

const char *stoa(double secs)
{
  static char seconds[40];
  char fulltime[20];
  int  ints = (int)(secs + 0.5);
  
  // Human-readable part
  if (secs > 3600)
    sprintf(fulltime, " (%dh %dm %ds)",
            (int)secs/3600, (ints%3600)/60, ints%60);
  else if (secs > 60)
    sprintf(fulltime, " (%dm %ds)", ints/60, ints%60);
  else
    fulltime[0] = '\0';
  
  // Machine-readable part
  if (secs > 10000)
    sprintf(seconds, "%8e", secs);
  else if (secs > 100)
    sprintf(seconds, "%ds", ints);
  else 
    sprintf(seconds, "%.2gs", secs);

  // Put them together  
  strcat(seconds, fulltime);

  return seconds;
}

void main(int argc, char *argv[])
{
  NXEventHandle evs;
  _NXSize_ size;
  NXMouseScaling acc;
  int i;
  BOOL doall = NO;
  
  evs = NXOpenEventStatus();
  if (evs == NULL)
  {
    perror("NXOpenEventStatus");
    exit(1);
  }

  if (argc < 2)
    usage(argv[0]);

  switch (argv[1][0])
  {
  case 'a':
    // We allow no args here!
    if (argc != 2)
      usage(argv[0]);
    doall = YES;
    // Now fall through almost everywhere!
  case 'l':		// l
  case 'x':		// xlist
    evsinfo(evs, argv[1][0] != 'l'); // for 'a' and 'x'
    // Here we add an additional newline
    if (doall)
      putchar('\n');
    else
      break;
  case 'k':		// keyrepeat
    if (argc > 2)
    {
      NXSetKeyRepeatThreshold(evs, atof(argv[2]));
      NXSetKeyRepeatInterval(evs, atof(argv[3]));
    }
    printf("Key Repeat Threshold:  %.2gs\n", NXKeyRepeatThreshold(evs));
    printf("Key Repeat Interval:   %.2gs\n", NXKeyRepeatInterval(evs));
    if (!doall) break;
  // KeyMapping, ResetKeyboard currently missing
  case 'c':		// click
    if (argc > 2)
    {
      NXSetClickTime(evs, atof(argv[2]));
      size.width = size.height = atof(argv[3]);
      NXSetClickSpace(evs, &size);
    }
    printf("Double-Click Time:     %.2gs\n", NXClickTime(evs));
    NXGetClickSpace(evs, &size);
    printf("Double-Click Space:    [%.2g,%.2g]\n", size.width, size.height);
    if (!doall) break;
  case 's':		// scaling
    // Enough parameters?
    if (argc > 2)
    {
      acc.numScaleLevels = atoi(argv[2]);
      if (acc.numScaleLevels > 0 || acc.numScaleLevels <= NX_MAXMOUSESCALINGS)
      {
	for (i = 0; i < acc.numScaleLevels; i++)
	{
	  acc.scaleThresholds[i] = atoi(argv[2*i + 3]);
	  acc.scaleFactors[i] = atoi(argv[2*i + 4]);
	}
	NXSetMouseScaling(evs, &acc);
      }
    }
    NXGetMouseScaling(evs, &acc);
    printf("Mouse Scaling:         %d", acc.numScaleLevels);
    for (i = 0; i < acc.numScaleLevels; i++)
      printf(" %d %d", acc.scaleThresholds[i], acc.scaleFactors[i]);
    putchar('\n');
    if (!doall) break;
  case 'm':		// menu button
    if (argc > 2)
      NXEnableMouseButton(evs, atoi(argv[2]));
    printf("Menu Button:           %s\n",
           string(button, NXMouseButtonEnabled(evs)));
    if (!doall) break;
  case 'b':		// brightness
    if (argc > 2)
      NXSetScreenBrightness(evs, atof(argv[2]));
    printf("Brightness:            %.2g\n", NXScreenBrightness(evs));
    if (!doall) break;
  case 'i':		// idle time (for dimming)
#if DNX_CURRENT_COMPILER_RELEASE >= 330
    printf("Idle Time:             %s\n", stoa(NXIdleTime(evs)));
#endif
    printf("Dimming In:            %s\n", stoa(NXAutoDimTime(evs)));
    if (!doall) break;
  case 'd':		// dimming parameters
    if (argc > 3)
    {
      NXSetAutoDimThreshold(evs, atof(argv[2]));
      NXSetAutoDimBrightness(evs, atof(argv[3]));
    }
    printf("Dim Time:              %s\n", stoa(NXAutoDimThreshold(evs)));
    printf("Dim Brightness:        %.2g\n", NXAutoDimBrightness(evs));
    if (!doall) break;
  case 'D':		// Dimmed?
    if (argc > 2)
      NXSetAutoDimState(evs, atob(argv[2]));
    printf("Dimmed:                %s\n", string(bool, NXAutoDimState(evs)));
    if (!doall) break;
  case 'v':		// Volume
    if (argc > 2)
      NXSetCurrentVolume(evs, atof(argv[2]));
    printf("Volume:                %.2g\n", NXCurrentVolume(evs));
    if (!doall) break;
  case 'w':		// wait cursor
    if (argc > 3)
    {
      NXSetWaitCursorThreshold(evs, atof(argv[2]));
      NXSetWaitCursorSustain(evs, atof(argv[3]));
    }
    printf("Wait Cursor After:     %s\n", stoa(NXWaitCursorThreshold(evs)));
    printf("Wait Cursor Stays:     %s\n", stoa(NXWaitCursorSustain(evs)));
    if (!doall) break;
  case 'W':		// wait cursor repetition
    if (argc > 2)
      NXSetWaitCursorFrameInterval(evs, atof(argv[2]));
    printf("Wait Cursor Speed:     %s\n", stoa(NXWaitCursorFrameInterval(evs)));
    break;
  default:
    usage(argv[0]);
  }
  
  NXCloseEventStatus(evs);
}

These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.