|
|
1.1 root 1: .TH XEMUL 4 "4.2A UNIX Manual"
2: .UC
3: .SH NAME
4: xemul \- X Input Emulator, for queuing keyboard and mouse events.
5: .SH SYNOPSIS
6: .nf
7: xemul
8: .fi
9: .SH DESCRIPTION
10: The X emulator is used for queuing input events from the keyboard and mouse
11: into a shared queue area between kernel and the user level X server.
12: This emulator follows the restrictions and conventions determined by X but
13: can be used by other user processes as well.
14: .PP
15: .B Starting the X Emulator
16: .br
17: Since the
18: .B X Emulator
19: is a non standard input emulator the user should open the non standard
20: console device
21: associated with the display being used e.g. (/dev/aed, /dev/apa8, etc.).
22: After the open the user should perform the EISETD ioctl command to set the
23: E_XINPUT emulator. The following piece of code would do this
24: initialization;
25: .IP
26: .DT
27: .sp 1
28: .nf
29: #include <machinecons/screen_conf.h>
30: #include <machinecons/xio.h>
31: main()
32: {
33: int fd, input_emul;
34:
35: fd = open ("/dev/apa16", O_RDWR);
36: input_emul = E_XINPUT;
37: ioctl (fd, EISETD, &input_emul);
38: }
39: .fi
40: .sp 1
41: .PP
42: Once you have set the input emulator to E_XINPUT all input from the
43: keyboard will be queued in shared memory. The normal
44: .B read system call
45: will return an error. As described in the emulator document when you open
46: the nonstandard device the output emulator will default to the buffer
47: emulator. This assumes that the user process will be taking over the
48: display and any write system calls will be buffered until the
49: user process gives up the display, see
50: .IR budemul (4).
51: Also see
52: .IR stdemul (4)
53: or
54: .IR ibmemul (4)
55: if you wish to change the output emulator back to the standard type emulator.
56: .PP
57: To have mouse events forwarded to the X input
58: emulator you must set the mouse to a special line discipline which forwards
59: to an input emulator. Please see
60: .IR tty_tb (4)
61: for more information.
62: Because the nonstandard emulator was open, if the process dies or
63: closes the device the default emulators will be restored.
64: .PP
65: The user process is responsible to
66: find out where the shared memory queue is, read input events off the head
67: of the queue, and update the head queue pointer.
68: .PP
69: The following structure is kept in shared memory and filled in when the
70: X emulator is opened.
71: .IP
72: .DT
73: .sp 1
74: .nf
75:
76: struct XBuffArea {
77: XIoAddr xioa; /* Queue and control information */
78: XEvent ibuff[XMAXEVQ]; /* Circular event queue */
79: };
80:
81: typedef struct _XIoAddr {
82: short status; /* Status of emulator (not used) */
83: XEvent *ibuff; /* Pointer to event queue */
84: int iqsize; /* Circular queue size (power of 2) */
85: int ihead; /* Queue head */
86: int itail; /* Queue tail */
87: XCursor mouse; /* Current Mouse position */
88: XCursor hotspot; /* Current Mouse hot spot */
89: XBox mbox; /* Current Mouse movement box */
90: int make_break; /* =0 then make =1 then break */
91: short mthreshold; /* Mouse motion parameter */
92: short mscale; /* Mouse scale factor (if negative
93: then do square). */
94: MSBox hmbox; /* Hide mouse box */
95: } XIoAddr;
96: typedef XIoAddr *XIoAddrAddr;
97: .fi
98: .PP
99: Once the user process sets the X input emulator the following code
100: shows the
101: .I ioctl
102: call and assignment which should
103: be performed to get the address of the above information.
104: .IP
105: .DT
106: .sp 1
107: .nf
108: XIoAddrAddr XAddr;
109: XEventQueue *queue;
110:
111: ioctl (fd, QIOCADDR, &XAddr);
112: queue = (XEventQueue *) (&XAddr->ibuff);
113: .fi
114: .sp 1
115: .PP
116: The last assignment above creates a pointer to the section of the shared
117: memory where the queue pointers and information are kept. The
118: .B XEventQueue
119: typedef,
120: .B XEvent
121: structure and defines shown below are defined in <machinecons/qevent.h>.
122: .IP
123: .DT
124: .sp 1
125: .nf
126: /* The event queue */
127:
128: typedef struct _X_eventqueue {
129: XEvent *events; /* input event buffer */
130: int size; /* size of event buffer */
131: int head; /* index into events */
132: int tail; /* index into events */
133: } XEventQueue;
134:
135: typedef struct _X_event {
136: u_short xe_x; /* x position */
137: u_short xe_y; /* y position */
138: u_short xe_time; /* 10 millisecond units (button only) */
139: u_char xe_type; /* button or motion? */
140: u_char xe_key; /* the key (button only) */
141: u_char xe_direction; /* which direction (button only) */
142: u_char xe_device; /* which device (button only) */
143: } XEvent;
144:
145: /* xe_type field */
146: #define XE_BUTTON 0 /* button moved */
147: #define XE_MMOTION 1 /* mouse moved */
148: #define XE_TMOTION 2 /* tablet moved */
149:
150: /* xe_direction field */
151: #define XE_KBTUP 0 /* up */
152: #define XE_KBTDOWN 1 /* down */
153: #define XE_KBTRAW 2 /* undetermined */
154:
155: /* xe_device field */
156: #define XE_MOUSE 1 /* mouse */
157: #define XE_DKB 2 /* main keyboard */
158: #define XE_TABLET 3 /* graphics tablet */
159: #define XE_AUX 4 /* auxiliary */
160: #define XE_CONSOLE 5 /* console */
161: .fi
162: .sp 1
163: .PP
164: At the start the head and tail indexes in the XEventQueue will both be
165: zero. When an event occurs the information will be stored at the
166: .B tail
167: and then the index will be bumped up by one. If the tail index has
168: reached the end of the queue it will wrap around to zero (circular
169: queue).
170: All input events will be ignored if the tail index catches up to
171: the head index.
172: .PP
173: The user should poll or issue a select to find out when on event occurs
174: (head != tail). The user should then process the information from the
175: event pointed to by the head index and then adjust the head index in the
176: same manor as described for the tail. The following code is an example of
177: this process:
178: .IP
179: .DT
180: .sp 1
181: .nf
182: XEvent *ev;
183:
184: while (queue->head != queue->tail) {
185: ev = &queue->events[queue->head];
186: switch (ev->xe_type) {
187: case XE_BUTTON: /* A key/button moved */
188: key_button_motion (ev);
189: break;
190: case XE_MMOTION: /* The mouse moved */
191: mouse_motion (ev);
192: break;
193: }
194: if (queue->head < queue->size)
195: queue->head++;
196: else
197: queue->head = 0;
198: }
199: .fi
200: .PP
201: .B Event Data
202: .br
203: The user need only to analyze the data in the event passed to determine
204: what has occurred. The
205: .B xe_x and xe_y
206: will always contain the current mouse (x, y) position for any event.
207: This same information is also always available in the mouse entry in the
208: XIoAddr structure.
209: The
210: .B xe_time
211: entry is a timestamp (in 10 millisecond units) marking that event.
212: .B xe_type
213: describes what type of event occurred, XE_BUTTON meaning a keyboard key
214: or mouse button event, XE_MMOTION meaning a mouse motion event, and
215: XE_TMOTION meaning a tablet motion event.
216: Only if the event was a XE_BUTTON will the
217: .B xe_key, xe_direction, and xe_device
218: fields be filled in accordingly.
219: The
220: .B xe_device
221: tells you it the event was from the keyboard, mouse, tablet, etc..
222: The
223: .B xe_key
224: will contain the keyboard key code or which mouse button.
225: The
226: .B xe_direction
227: will tell you if the key/button was depressed or let go (DOWN or UP)..
228: Button events are always presented as new events.
229: See hardware documentation for the keyboard codes and see
230: .IR tty_tb (4)
231: for the mouse button report.
232: .PP
233: .B Motion Events
234: .br
235: Motion events are
236: joined if the previous event was a motion and the user had not read it
237: yet. As stated before the current mouse position is always kept in the
238: shared memory structure
239: .B XIoAddr.mouse.
240: Motion events are not always reported as an event to the user. The user
241: may set the mouse motion box,
242: .B XIoAddr.mbox,
243: to a rectangle in which motion events should not be reported. This is a
244: key feature to the X emulator which optimizes events to only those the
245: user cares about. This is possible since the X emulator tracks the mouse
246: with the cursor/locator on the screen being used. Since the user is not
247: responsible for tracking the mouse on the screen it doesn't need to know
248: every motion event.
249: .IP
250: .DT
251: .nf
252: .sp 1
253: /* mouse motion rectangle */
254: typedef struct _X_box {
255: short bottom;
256: short right;
257: short left;
258: short top;
259: } XBox;
260: .fi
261: .PP
262: .B Cursor/Locator Control
263: .br
264: The user can perform the following ioctls for controlling the mouse cursor
265: tracking.
266: .TP 20
267: QIOCADDR
268: The user passes an XIoAddr address which is filled with the address in
269: shared memory where the structure will be found.
270: .TP 20
271: QIOCSMSTATE
272: Set the mouse state. The user passes the
273: .I XCursor
274: structure to specify the new mouse position.
275: .TP 20
276: QIOCLDCUR
277: The user passes a
278: .I QIOLocator
279: structure indicating what the cursor/locator bitmap should be on the
280: display.
281: .TP 20
282: QIOCHIDECUR
283: This ioctl will inhibit the cursor/locator from being displayed on the
284: screen. The cursor will still be tracked and reported to the user.
285: .TP 20
286: QIOCSHOWCUR
287: The user issues this ioctl to show the cursor/locator after it was been
288: hidden. The locator will appear at it's current location (not where it
289: was hidden). The locator defaults to show.
290: .PP
291: The structures mentioned above are shown below:
292: .IP
293: .DT
294: .nf
295: .sp 1
296: /* mouse cursor position */
297: typedef struct _X_cursor {
298: short x;
299: short y;
300: } XCursor;
301: .sp 1
302: /* Mouse locator bitmap */
303: typedef struct
304: {
305: short data[16];
306: short mask[16];
307: struct {
308: short v, h;
309: } hotSpot;
310: } QIOLocator;
311: .fi
312: .PP
313: Besides the above ioctls the user can control the mouse cursor/locator by
314: writing into the XIoAddr shared memory structure. The following is a
315: synopsis of each remaining part of this structure:
316: .TP 15
317: mouse
318: The current mouse position.
319: .I XCursor
320: structure.
321: .TP 15
322: hotspot
323: Current Mouse hot spot offset from the mouse position.
324: .I XCursor
325: structure.
326: .TP 15
327: mbox
328: Current Mouse movement box.
329: .I XBox
330: structure.
331: .TP 15
332: mthreshold
333: Mouse motion parameter (not used currently).
334: .TP 15
335: mscale
336: Mouse scale factor, if negative then do square (not used currently).
337: .TP 15
338: hmbox
339: Hide mouse box, which the user specifies to tell the X emulator a
340: rectangle in which it should hide the mouse. The emulator passes this box
341: to the hardware locator routines mainly so software driven
342: cursors will not be displayed within this box.
343: This is only used by displays with no hardware cursor support which need
344: to know when to get the software cursor out of the way.
345: .sp 1
346: .IP
347: .DT
348: .nf
349: typedef struct {
350: short bottom;
351: short top;
352: short left;
353: short right;
354: int flags; /* 0 - not active, 1 - active */
355: } MSBox;
356: .fi
357: .sp 1
358: .PP
359: .B Keyboard Ioctl Control
360: .br
361: .TP 20
362: QIOCBELL
363: Ring keyboard bell with integer volume passed from 0 (off) to 7 (loud).
364: .TP 20
365: QIOCCLICK
366: Set autokeyclick to integer volume passed between -1 (default), 0 (off)
367: and 8 (loud).
368: .TP 20
369: QIOCAUTOREP
370: Turn keyboard keys autorepeat (1) on or (0) off, integer argument.
371: .TP 20
372: QIOCSETCAPSL
373: Turn on Caps Lock light on keyboard.
374: .TP 20
375: QIOCCLRCAPSL
376: Turn off Caps Lock light on keyboard.
377: .TP 20
378: QIOCSETNUML
379: Turn on Num Lock light on keyboard.
380: .TP 20
381: QIOCCLRNUML
382: Turn off Num Lock light on keyboard.
383: .TP 20
384: QIOCSETSCROLLL
385: Turn on Scroll Lock light on keyboard.
386: .TP 20
387: QIOCCLRSCROLLL
388: Turn off Scroll Lock light on keyboard.
389: .SH FILES
390: .nf
391: /dev/aed ACIS Expiremental display nonstandard device.
392: /dev/apa8 APA8 display nonstandard device.
393: /dev/apa8c APA8 Color display nonstandard device.
394: /dev/apa16 APA16 display nonstandard device.
395: .fi
396: .SH "SEE ALSO"
397: Emulators in Workstation Unix,
398: bufemul(4),
399: stdemul(4),
400: kbdemul(4),
401: tty_tb(4)
402: .SH "BUGS"
403: Should implement the mouse threshold and scale features.
404: .SH "AUTHOR"
405: David O. Bundy
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.