1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
|
/*
* Please note that the comments on this file may be out of date
* and that they represent what I have figured about the shmiq device
* so far in IRIX.
*
* This also contains some streams and idev bits.
*
* They may contain errors, please, refer to the source code of the Linux
* kernel for a definitive answer on what we have implemented
*
* Miguel.
*/
/* STREAMs ioctls */
#define STRIOC ('S' << 8)
#define I_STR (STRIOC | 010)
#define I_PUSH (STRIOC | 02)
#define I_LINK (STRIOC | 014)
#define I_UNLINK (STRIOC | 015)
/* Data structure passed on I_STR ioctls */
struct strioctl {
int ic_cmd; /* streams ioctl command */
int ic_timout; /* timeout */
int ic_len; /* lenght of data */
void *ic_dp; /* data */
};
/*
* For mapping the shared memory input queue, you have to:
*
* 1. Map /dev/zero for the number of bytes you want to use
* for your shared memory input queue plus the size of the
* sharedMemoryInputQueue structure + 4 (I still have not figured
* what this one is for
*
* 2. Open /dev/shmiq
*
* 3. Open /dev/qcntlN N is [0..Nshmiqs]
*
* 4. Fill a shmiqreq structure. user_vaddr should point to the return
* address from the /dev/zero mmap. Arg is the number of shmqevents
* that fit into the /dev/zero region (remember that at the beginning there
* is a sharedMemoryInputQueue header).
*
* 5. Issue the ioctl (qcntlfd, QIOCATTACH, &your_shmiqreq);
*/
struct shmiqreq {
char *user_vaddr;
int arg;
};
/* map the shmiq into the process address space */
#define QIOCATTACH _IOW('Q',1,struct shmiqreq)
/* remove mappings */
#define QIOCDETACH _IO('Q',2)
/*
* A shared memory input queue event.
*/
struct shmqdata {
unsigned char device; /* device major */
unsigned char which; /* device minor */
unsigned char type; /* event type */
unsigned char flags; /* little event data */
union {
int pos; /* big event data */
short ptraxis [2]; /* event data for PTR events */
} un;
};
/* indetifies the shmiq and the device */
struct shmiqlinkid {
short int devminor;
short int index;
};
struct shmqevent {
union {
int time;
struct shmiqlinkid id;
} un ;
struct shmqdata data ;
};
/*
* sharedMemoryInputQueue: this describes the shared memory input queue.
*
* head is the user index into the events, user can modify this one.
* tail is managed by the kernel.
* flags is one of SHMIQ_OVERFLOW or SHMIQ_CORRUPTED
* if OVERFLOW is set it seems ioctl QUIOCSERVICED should be called
* to notify the kernel.
* events where the kernel sticks the events.
*/
struct sharedMemoryInputQueue {
volatile int head; /* user's index into events */
volatile int tail; /* kernel's index into events */
volatile unsigned int flags; /* place for out-of-band data */
#define SHMIQ_OVERFLOW 1
#define SHMIQ_CORRUPTED 2
struct shmqevent events[1]; /* input event buffer */
};
/* have to figure this one out */
#define QIOCGETINDX _IOWR('Q', 8, int)
/* acknowledge shmiq overflow */
#define QIOCSERVICED _IO('Q', 3)
/* Double indirect I_STR ioctl, yeah, fun fun fun */
struct muxioctl {
int index; /* lower stream index */
int realcmd; /* the actual command for the subdevice */
};
/* Double indirect ioctl */
#define QIOCIISTR _IOW('Q', 7, struct muxioctl)
/* Cursor ioclts: */
/* set cursor tracking mode */
#define QIOCURSTRK _IOW('Q', 4, int)
/* set cursor filter box */
#define QIOCURSIGN _IOW('Q', 5, int [4])
/* set cursor axes */
struct shmiqsetcurs {
short index;
short axes;
};
#define QIOCSETCURS _IOWR('Q', 9, struct shmiqsetcurs)
/* set cursor position */
struct shmiqsetcpos {
short x;
short y;
};
#define QIOCSETCPOS _IOWR('Q', 10, struct shmiqsetcpos)
/* get time since last event */
#define QIOCGETITIME _IOR('Q', 11, time_t)
/* set curent screen */
#define QIOCSETSCRN _IOW('Q',6,int)
/* -------------------- iDev stuff -------------------- */
#define IDEV_MAX_NAME_LEN 15
#define IDEV_MAX_TYPE_LEN 15
typedef struct {
char devName[IDEV_MAX_NAME_LEN+1];
char devType[IDEV_MAX_TYPE_LEN+1];
unsigned short nButtons;
unsigned short nValuators;
unsigned short nLEDs;
unsigned short nStrDpys;
unsigned short nIntDpys;
unsigned char nBells;
unsigned char flags;
#define IDEV_HAS_KEYMAP 0x01
#define IDEV_HAS_PROXIMITY 0x02
#define IDEV_HAS_PCKBD 0x04
} idevDesc;
typedef struct {
char *nothing_for_now;
} idevInfo;
#define IDEV_KEYMAP_NAME_LEN 15
typedef struct {
char name[IDEV_KEYMAP_NAME_LEN+1];
} idevKeymapDesc;
/* The valuator definition */
typedef struct {
unsigned hwMinRes;
unsigned hwMaxRes;
int hwMinVal;
int hwMaxVal;
unsigned char possibleModes;
#define IDEV_ABSOLUTE 0x0
#define IDEV_RELATIVE 0x1
#define IDEV_EITHER 0x2
unsigned char mode; /* One of: IDEV_ABSOLUTE, IDEV_RELATIVE */
unsigned short resolution;
int minVal;
int maxVal;
} idevValuatorDesc;
/* This is used to query a specific valuator with the IDEVGETVALUATORDESC ioctl */
typedef struct {
short valNum;
unsigned short flags;
idevValuatorDesc desc;
} idevGetSetValDesc;
#define IDEVGETDEVICEDESC _IOWR('i', 0, idevDesc)
#define IDEVGETVALUATORDESC _IOWR('i', 1, idevGetSetValDesc)
#define IDEVGETKEYMAPDESC _IOWR('i', 2, idevKeymapDesc)
#define IDEVINITDEVICE _IOW ('i', 51, unsigned int)
#ifdef __KERNEL__
/* These are only interpreted by SHMIQ-attacheable devices and are internal
* to the kernel
*/
#define SHMIQ_OFF _IO('Q',1)
#define SHMIQ_ON _IO('Q',2)
void shmiq_push_event (struct shmqevent *e);
int get_sioc (struct strioctl *sioc, unsigned long arg);
#endif
|