1/* $XFree86: xc/programs/xsetpointer/xsetpointer.c,v 3.7 2003/05/27 22:27:10 tsi Exp $ */
2
3/*
4 * Copyright 1995 by Frederic Lepied, France. <fred@sugix.frmug.fr.net>
5 *
6 * Permission to use, copy, modify, distribute, and sell this software and its
7 * documentation for any purpose is  hereby granted without fee, provided that
8 * the  above copyright   notice appear  in   all  copies and  that both  that
9 * copyright  notice   and   this  permission   notice  appear  in  supporting
10 * documentation, and that   the  name of  Frederic   Lepied not  be  used  in
11 * advertising or publicity pertaining to distribution of the software without
12 * specific,  written      prior  permission.     Frederic  Lepied   makes  no
13 * representations about the suitability of this software for any purpose.  It
14 * is provided "as is" without express or implied warranty.
15 *
16 * FREDERIC  LEPIED DISCLAIMS ALL   WARRANTIES WITH REGARD  TO  THIS SOFTWARE,
17 * INCLUDING ALL IMPLIED   WARRANTIES OF MERCHANTABILITY  AND   FITNESS, IN NO
18 * EVENT  SHALL FREDERIC  LEPIED BE   LIABLE   FOR ANY  SPECIAL, INDIRECT   OR
19 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
20 * DATA  OR PROFITS, WHETHER  IN  AN ACTION OF  CONTRACT,  NEGLIGENCE OR OTHER
21 * TORTIOUS  ACTION, ARISING    OUT OF OR   IN  CONNECTION  WITH THE USE    OR
22 * PERFORMANCE OF THIS SOFTWARE.
23 *
24 */
25
26#include <stdio.h>
27#include <stdlib.h>
28#include <string.h>
29#include <ctype.h>
30#include <X11/Xproto.h>
31#include <X11/extensions/XInput.h>
32
33int           event_type;
34
35static int
36StrCaseCmp(char *s1, char *s2)
37{
38	char c1, c2;
39
40	if (*s1 == 0) {
41		if (*s2 == 0)
42			return(0);
43		else
44			return(1);
45	}
46	c1 = (isupper(*s1) ? tolower(*s1) : *s1);
47	c2 = (isupper(*s2) ? tolower(*s2) : *s2);
48	while (c1 == c2)
49	{
50		if (c1 == '\0')
51			return(0);
52		s1++; s2++;
53		c1 = (isupper(*s1) ? tolower(*s1) : *s1);
54		c2 = (isupper(*s2) ? tolower(*s2) : *s2);
55	}
56	return(c1 - c2);
57}
58
59int
60main(int argc, char * argv[])
61{
62  int                loop, num_extensions, num_devices;
63  char               **extensions;
64  XDeviceInfo        *devices;
65  XDeviceCoreControl corectl;
66  Display            *dpy;
67  int		     list = 0, core = 0;
68  XDevice            *device;
69
70  if (argc < 2 || argc > 3) {
71    fprintf(stderr, "usage : %s (-l | -c | +c ) <device name>)\n", argv[0]);
72    exit(1);
73  }
74
75  if (strcmp(argv[1], "-l") == 0) {
76    list = 1;
77  }
78  else if (strcmp(argv[1], "-c") == 0) {
79    core = 1;
80  }
81  else if (strcmp(argv[1], "+c") == 0) {
82    core = 2;
83  }
84
85  dpy = XOpenDisplay(NULL);
86
87  if (!dpy) {
88    printf("unable to connect to X Server try to set the DISPLAY variable\n");
89    exit(1);
90  }
91
92#ifdef DEBUG
93  printf("connected to %s\n", XDisplayString(dpy));
94#endif
95
96  extensions = XListExtensions(dpy, &num_extensions);
97  for (loop = 0; loop < num_extensions &&
98         (strcmp(extensions[loop], "XInputExtension") != 0); loop++);
99  XFreeExtensionList(extensions);
100  if (loop != num_extensions)
101    {
102      devices = XListInputDevices(dpy, &num_devices);
103      for(loop=0; loop<num_devices; loop++)
104        {
105	  if (list) {
106	      printf("%d: \"%s\"	[", (int)devices[loop].id, devices[loop].name ? devices[loop].name : "<noname>");
107	      switch(devices[loop].use) {
108	      case IsXPointer:
109		  printf("XPointer]\n");
110		  break;
111	      case IsXKeyboard:
112		  printf("XKeyboard]\n");
113		  break;
114	      case IsXExtensionDevice:
115		  printf("XExtensionDevice]\n");
116		  break;
117              case IsXExtensionKeyboard:
118                  printf("XExtensionKeyboard]\n");
119                  break;
120              case IsXExtensionPointer:
121                  printf("XExtensionPointer]\n");
122                  break;
123	      default:
124		  printf("invalid value]\n");
125		  break;
126	      }
127	  }
128          else if (core) {
129            if (argc == 3 && devices[loop].name &&
130                StrCaseCmp(devices[loop].name, argv[2]) == 0) {
131#ifdef DEBUG
132                fprintf(stderr, "opening device %s at %d\n",
133                        devices[loop].name ? devices[loop].name : "<noname>",
134                        devices[loop].id);
135#endif
136              device = XOpenDevice(dpy, devices[loop].id);
137              if (device) {
138                corectl.status = (core - 1);
139                corectl.length = sizeof(corectl);
140                corectl.control = DEVICE_CORE;
141                XChangeDeviceControl(dpy, device, DEVICE_CORE,
142                                     (XDeviceControl *)&corectl);
143                exit(0);
144              }
145              else {
146                fprintf(stderr, "error opening device\n");
147                exit(1);
148              }
149            }
150          }
151	  else {
152          if ((argc == 2) && devices[loop].name &&
153              (StrCaseCmp(devices[loop].name, argv[1]) == 0))
154            if (devices[loop].use == IsXExtensionDevice)
155              {
156#ifdef DEBUG
157                fprintf(stderr, "opening device %s\n",
158                        devices[loop].name ? devices[loop].name : "<noname>");
159#endif
160                device = XOpenDevice(dpy, devices[loop].id);
161                if (device)
162                  {
163                    XChangePointerDevice(dpy, device, 0, 1);
164                    exit(0);
165                  }
166                else
167                  {
168                    fprintf(stderr, "error opening device\n");
169                    exit(1);
170                  }
171              }
172	  }
173        }
174      XFreeDeviceList(devices);
175    }
176  else
177    {
178      fprintf(stderr, "No XInput extension available\n");
179      exit(1);
180    }
181
182  if (list) {
183    exit(0);
184  }
185  else {
186    fprintf(stderr, "Extended device %s not found\n", core ? argv[2] :
187                                                             argv[1]);
188    exit(1);
189  }
190}
191