|
|
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.