qemu/include/hw/xen/interface/io/kbdif.h
<<
>>
Prefs
   1/*
   2 * kbdif.h -- Xen virtual keyboard/mouse
   3 *
   4 * Permission is hereby granted, free of charge, to any person obtaining a copy
   5 * of this software and associated documentation files (the "Software"), to
   6 * deal in the Software without restriction, including without limitation the
   7 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
   8 * sell copies of the Software, and to permit persons to whom the Software is
   9 * furnished to do so, subject to the following conditions:
  10 *
  11 * The above copyright notice and this permission notice shall be included in
  12 * all copies or substantial portions of the Software.
  13 *
  14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  19 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  20 * DEALINGS IN THE SOFTWARE.
  21 *
  22 * Copyright (C) 2005 Anthony Liguori <aliguori@us.ibm.com>
  23 * Copyright (C) 2006 Red Hat, Inc., Markus Armbruster <armbru@redhat.com>
  24 */
  25
  26#ifndef __XEN_PUBLIC_IO_KBDIF_H__
  27#define __XEN_PUBLIC_IO_KBDIF_H__
  28
  29/*
  30 *****************************************************************************
  31 *                     Feature and Parameter Negotiation
  32 *****************************************************************************
  33 *
  34 * The two halves of a para-virtual driver utilize nodes within
  35 * XenStore to communicate capabilities and to negotiate operating parameters.
  36 * This section enumerates these nodes which reside in the respective front and
  37 * backend portions of XenStore, following XenBus convention.
  38 *
  39 * All data in XenStore is stored as strings.  Nodes specifying numeric
  40 * values are encoded in decimal. Integer value ranges listed below are
  41 * expressed as fixed sized integer types capable of storing the conversion
  42 * of a properly formated node string, without loss of information.
  43 *
  44 *****************************************************************************
  45 *                            Backend XenBus Nodes
  46 *****************************************************************************
  47 *
  48 *---------------------------- Features supported ----------------------------
  49 *
  50 * Capable backend advertises supported features by publishing
  51 * corresponding entries in XenStore and puts 1 as the value of the entry.
  52 * If a feature is not supported then 0 must be set or feature entry omitted.
  53 *
  54 * feature-disable-keyboard
  55 *      Values:         <uint>
  56 *
  57 *      If there is no need to expose a virtual keyboard device by the
  58 *      frontend then this must be set to 1.
  59 *
  60 * feature-disable-pointer
  61 *      Values:         <uint>
  62 *
  63 *      If there is no need to expose a virtual pointer device by the
  64 *      frontend then this must be set to 1.
  65 *
  66 * feature-abs-pointer
  67 *      Values:         <uint>
  68 *
  69 *      Backends, which support reporting of absolute coordinates for pointer
  70 *      device should set this to 1.
  71 *
  72 * feature-multi-touch
  73 *      Values:         <uint>
  74 *
  75 *      Backends, which support reporting of multi-touch events
  76 *      should set this to 1.
  77 *
  78 * feature-raw-pointer
  79 *      Values:        <uint>
  80 *
  81 *      Backends, which support reporting raw (unscaled) absolute coordinates
  82 *      for pointer devices should set this to 1. Raw (unscaled) values have
  83 *      a range of [0, 0x7fff].
  84 *
  85 *-----------------------  Device Instance Parameters ------------------------
  86 *
  87 * unique-id
  88 *      Values:         <string>
  89 *
  90 *      After device instance initialization it is assigned a unique ID,
  91 *      so every instance of the frontend can be identified by the backend
  92 *      by this ID. This can be UUID or such.
  93 *
  94 *------------------------- Pointer Device Parameters ------------------------
  95 *
  96 * width
  97 *      Values:         <uint>
  98 *
  99 *      Maximum X coordinate (width) to be used by the frontend
 100 *      while reporting input events, pixels, [0; UINT32_MAX].
 101 *
 102 * height
 103 *      Values:         <uint>
 104 *
 105 *      Maximum Y coordinate (height) to be used by the frontend
 106 *      while reporting input events, pixels, [0; UINT32_MAX].
 107 *
 108 *----------------------- Multi-touch Device Parameters ----------------------
 109 *
 110 * multi-touch-num-contacts
 111 *      Values:         <uint>
 112 *
 113 *      Number of simultaneous touches reported.
 114 *
 115 * multi-touch-width
 116 *      Values:         <uint>
 117 *
 118 *      Width of the touch area to be used by the frontend
 119 *      while reporting input events, pixels, [0; UINT32_MAX].
 120 *
 121 * multi-touch-height
 122 *      Values:         <uint>
 123 *
 124 *      Height of the touch area to be used by the frontend
 125 *      while reporting input events, pixels, [0; UINT32_MAX].
 126 *
 127 *****************************************************************************
 128 *                            Frontend XenBus Nodes
 129 *****************************************************************************
 130 *
 131 *------------------------------ Feature request -----------------------------
 132 *
 133 * Capable frontend requests features from backend via setting corresponding
 134 * entries to 1 in XenStore. Requests for features not advertised as supported
 135 * by the backend have no effect.
 136 *
 137 * request-abs-pointer
 138 *      Values:         <uint>
 139 *
 140 *      Request backend to report absolute pointer coordinates
 141 *      (XENKBD_TYPE_POS) instead of relative ones (XENKBD_TYPE_MOTION).
 142 *
 143 * request-multi-touch
 144 *      Values:         <uint>
 145 *
 146 *      Request backend to report multi-touch events.
 147 *
 148 * request-raw-pointer
 149 *      Values:         <uint>
 150 *
 151 *      Request backend to report raw unscaled absolute pointer coordinates.
 152 *      This option is only valid if request-abs-pointer is also set.
 153 *      Raw unscaled coordinates have the range [0, 0x7fff]
 154 *
 155 *----------------------- Request Transport Parameters -----------------------
 156 *
 157 * event-channel
 158 *      Values:         <uint>
 159 *
 160 *      The identifier of the Xen event channel used to signal activity
 161 *      in the ring buffer.
 162 *
 163 * page-gref
 164 *      Values:         <uint>
 165 *
 166 *      The Xen grant reference granting permission for the backend to map
 167 *      a sole page in a single page sized event ring buffer.
 168 *
 169 * page-ref
 170 *      Values:         <uint>
 171 *
 172 *      OBSOLETE, not recommended for use.
 173 *      PFN of the shared page.
 174 */
 175
 176/*
 177 * EVENT CODES.
 178 */
 179
 180#define XENKBD_TYPE_MOTION             1
 181#define XENKBD_TYPE_RESERVED           2
 182#define XENKBD_TYPE_KEY                3
 183#define XENKBD_TYPE_POS                4
 184#define XENKBD_TYPE_MTOUCH             5
 185
 186/* Multi-touch event sub-codes */
 187
 188#define XENKBD_MT_EV_DOWN              0
 189#define XENKBD_MT_EV_UP                1
 190#define XENKBD_MT_EV_MOTION            2
 191#define XENKBD_MT_EV_SYN               3
 192#define XENKBD_MT_EV_SHAPE             4
 193#define XENKBD_MT_EV_ORIENT            5
 194
 195/*
 196 * CONSTANTS, XENSTORE FIELD AND PATH NAME STRINGS, HELPERS.
 197 */
 198
 199#define XENKBD_DRIVER_NAME             "vkbd"
 200
 201#define XENKBD_FIELD_FEAT_DSBL_KEYBRD  "feature-disable-keyboard"
 202#define XENKBD_FIELD_FEAT_DSBL_POINTER "feature-disable-pointer"
 203#define XENKBD_FIELD_FEAT_ABS_POINTER  "feature-abs-pointer"
 204#define XENKBD_FIELD_FEAT_RAW_POINTER  "feature-raw-pointer"
 205#define XENKBD_FIELD_FEAT_MTOUCH       "feature-multi-touch"
 206#define XENKBD_FIELD_REQ_ABS_POINTER   "request-abs-pointer"
 207#define XENKBD_FIELD_REQ_RAW_POINTER   "request-raw-pointer"
 208#define XENKBD_FIELD_REQ_MTOUCH        "request-multi-touch"
 209#define XENKBD_FIELD_RING_GREF         "page-gref"
 210#define XENKBD_FIELD_EVT_CHANNEL       "event-channel"
 211#define XENKBD_FIELD_WIDTH             "width"
 212#define XENKBD_FIELD_HEIGHT            "height"
 213#define XENKBD_FIELD_MT_WIDTH          "multi-touch-width"
 214#define XENKBD_FIELD_MT_HEIGHT         "multi-touch-height"
 215#define XENKBD_FIELD_MT_NUM_CONTACTS   "multi-touch-num-contacts"
 216#define XENKBD_FIELD_UNIQUE_ID         "unique-id"
 217
 218/* OBSOLETE, not recommended for use */
 219#define XENKBD_FIELD_RING_REF          "page-ref"
 220
 221/*
 222 *****************************************************************************
 223 * Description of the protocol between frontend and backend driver.
 224 *****************************************************************************
 225 *
 226 * The two halves of a Para-virtual driver communicate with
 227 * each other using a shared page and an event channel.
 228 * Shared page contains a ring with event structures.
 229 *
 230 * All reserved fields in the structures below must be 0.
 231 *
 232 *****************************************************************************
 233 *                           Backend to frontend events
 234 *****************************************************************************
 235 *
 236 * Frontends should ignore unknown in events.
 237 * All event packets have the same length (40 octets)
 238 * All event packets have common header:
 239 *
 240 *          0         octet
 241 * +-----------------+
 242 * |       type      |
 243 * +-----------------+
 244 * type - uint8_t, event code, XENKBD_TYPE_???
 245 *
 246 *
 247 * Pointer relative movement event
 248 *         0                1                 2               3        octet
 249 * +----------------+----------------+----------------+----------------+
 250 * |  _TYPE_MOTION  |                     reserved                     | 4
 251 * +----------------+----------------+----------------+----------------+
 252 * |                               rel_x                               | 8
 253 * +----------------+----------------+----------------+----------------+
 254 * |                               rel_y                               | 12
 255 * +----------------+----------------+----------------+----------------+
 256 * |                               rel_z                               | 16
 257 * +----------------+----------------+----------------+----------------+
 258 * |                             reserved                              | 20
 259 * +----------------+----------------+----------------+----------------+
 260 * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
 261 * +----------------+----------------+----------------+----------------+
 262 * |                             reserved                              | 40
 263 * +----------------+----------------+----------------+----------------+
 264 *
 265 * rel_x - int32_t, relative X motion
 266 * rel_y - int32_t, relative Y motion
 267 * rel_z - int32_t, relative Z motion (wheel)
 268 */
 269
 270struct xenkbd_motion
 271{
 272    uint8_t type;
 273    int32_t rel_x;
 274    int32_t rel_y;
 275    int32_t rel_z;
 276};
 277
 278/*
 279 * Key event (includes pointer buttons)
 280 *         0                1                 2               3        octet
 281 * +----------------+----------------+----------------+----------------+
 282 * |  _TYPE_KEY     |     pressed    |            reserved             | 4
 283 * +----------------+----------------+----------------+----------------+
 284 * |                              keycode                              | 8
 285 * +----------------+----------------+----------------+----------------+
 286 * |                             reserved                              | 12
 287 * +----------------+----------------+----------------+----------------+
 288 * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
 289 * +----------------+----------------+----------------+----------------+
 290 * |                             reserved                              | 40
 291 * +----------------+----------------+----------------+----------------+
 292 *
 293 * pressed - uint8_t, 1 if pressed; 0 otherwise
 294 * keycode - uint32_t, KEY_* from linux/input.h
 295 */
 296
 297struct xenkbd_key
 298{
 299    uint8_t type;
 300    uint8_t pressed;
 301    uint32_t keycode;
 302};
 303
 304/*
 305 * Pointer absolute position event
 306 *         0                1                 2               3        octet
 307 * +----------------+----------------+----------------+----------------+
 308 * |  _TYPE_POS     |                     reserved                     | 4
 309 * +----------------+----------------+----------------+----------------+
 310 * |                               abs_x                               | 8
 311 * +----------------+----------------+----------------+----------------+
 312 * |                               abs_y                               | 12
 313 * +----------------+----------------+----------------+----------------+
 314 * |                               rel_z                               | 16
 315 * +----------------+----------------+----------------+----------------+
 316 * |                             reserved                              | 20
 317 * +----------------+----------------+----------------+----------------+
 318 * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
 319 * +----------------+----------------+----------------+----------------+
 320 * |                             reserved                              | 40
 321 * +----------------+----------------+----------------+----------------+
 322 *
 323 * abs_x - int32_t, absolute X position (in FB pixels)
 324 * abs_y - int32_t, absolute Y position (in FB pixels)
 325 * rel_z - int32_t, relative Z motion (wheel)
 326 */
 327
 328struct xenkbd_position
 329{
 330    uint8_t type;
 331    int32_t abs_x;
 332    int32_t abs_y;
 333    int32_t rel_z;
 334};
 335
 336/*
 337 * Multi-touch event and its sub-types
 338 *
 339 * All multi-touch event packets have common header:
 340 *
 341 *         0                1                 2               3        octet
 342 * +----------------+----------------+----------------+----------------+
 343 * |  _TYPE_MTOUCH  |   event_type   |   contact_id   |    reserved    | 4
 344 * +----------------+----------------+----------------+----------------+
 345 * |                             reserved                              | 8
 346 * +----------------+----------------+----------------+----------------+
 347 *
 348 * event_type - unt8_t, multi-touch event sub-type, XENKBD_MT_EV_???
 349 * contact_id - unt8_t, ID of the contact
 350 *
 351 * Touch interactions can consist of one or more contacts.
 352 * For each contact, a series of events is generated, starting
 353 * with a down event, followed by zero or more motion events,
 354 * and ending with an up event. Events relating to the same
 355 * contact point can be identified by the ID of the sequence: contact ID.
 356 * Contact ID may be reused after XENKBD_MT_EV_UP event and
 357 * is in the [0; XENKBD_FIELD_NUM_CONTACTS - 1] range.
 358 *
 359 * For further information please refer to documentation on Wayland [1],
 360 * Linux [2] and Windows [3] multi-touch support.
 361 *
 362 * [1] https://cgit.freedesktop.org/wayland/wayland/tree/protocol/wayland.xml
 363 * [2] https://www.kernel.org/doc/Documentation/input/multi-touch-protocol.txt
 364 * [3] https://msdn.microsoft.com/en-us/library/jj151564(v=vs.85).aspx
 365 *
 366 *
 367 * Multi-touch down event - sent when a new touch is made: touch is assigned
 368 * a unique contact ID, sent with this and consequent events related
 369 * to this touch.
 370 *         0                1                 2               3        octet
 371 * +----------------+----------------+----------------+----------------+
 372 * |  _TYPE_MTOUCH  |   _MT_EV_DOWN  |   contact_id   |    reserved    | 4
 373 * +----------------+----------------+----------------+----------------+
 374 * |                             reserved                              | 8
 375 * +----------------+----------------+----------------+----------------+
 376 * |                               abs_x                               | 12
 377 * +----------------+----------------+----------------+----------------+
 378 * |                               abs_y                               | 16
 379 * +----------------+----------------+----------------+----------------+
 380 * |                             reserved                              | 20
 381 * +----------------+----------------+----------------+----------------+
 382 * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
 383 * +----------------+----------------+----------------+----------------+
 384 * |                             reserved                              | 40
 385 * +----------------+----------------+----------------+----------------+
 386 *
 387 * abs_x - int32_t, absolute X position, in pixels
 388 * abs_y - int32_t, absolute Y position, in pixels
 389 *
 390 * Multi-touch contact release event
 391 *         0                1                 2               3        octet
 392 * +----------------+----------------+----------------+----------------+
 393 * |  _TYPE_MTOUCH  |  _MT_EV_UP     |   contact_id   |    reserved    | 4
 394 * +----------------+----------------+----------------+----------------+
 395 * |                             reserved                              | 8
 396 * +----------------+----------------+----------------+----------------+
 397 * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
 398 * +----------------+----------------+----------------+----------------+
 399 * |                             reserved                              | 40
 400 * +----------------+----------------+----------------+----------------+
 401 *
 402 * Multi-touch motion event
 403 *         0                1                 2               3        octet
 404 * +----------------+----------------+----------------+----------------+
 405 * |  _TYPE_MTOUCH  |  _MT_EV_MOTION |   contact_id   |    reserved    | 4
 406 * +----------------+----------------+----------------+----------------+
 407 * |                             reserved                              | 8
 408 * +----------------+----------------+----------------+----------------+
 409 * |                               abs_x                               | 12
 410 * +----------------+----------------+----------------+----------------+
 411 * |                               abs_y                               | 16
 412 * +----------------+----------------+----------------+----------------+
 413 * |                             reserved                              | 20
 414 * +----------------+----------------+----------------+----------------+
 415 * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
 416 * +----------------+----------------+----------------+----------------+
 417 * |                             reserved                              | 40
 418 * +----------------+----------------+----------------+----------------+
 419 *
 420 * abs_x - int32_t, absolute X position, in pixels,
 421 * abs_y - int32_t, absolute Y position, in pixels,
 422 *
 423 * Multi-touch input synchronization event - shows end of a set of events
 424 * which logically belong together.
 425 *         0                1                 2               3        octet
 426 * +----------------+----------------+----------------+----------------+
 427 * |  _TYPE_MTOUCH  |  _MT_EV_SYN    |   contact_id   |    reserved    | 4
 428 * +----------------+----------------+----------------+----------------+
 429 * |                             reserved                              | 8
 430 * +----------------+----------------+----------------+----------------+
 431 * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
 432 * +----------------+----------------+----------------+----------------+
 433 * |                             reserved                              | 40
 434 * +----------------+----------------+----------------+----------------+
 435 *
 436 * Multi-touch shape event - touch point's shape has changed its shape.
 437 * Shape is approximated by an ellipse through the major and minor axis
 438 * lengths: major is the longer diameter of the ellipse and minor is the
 439 * shorter one. Center of the ellipse is reported via
 440 * XENKBD_MT_EV_DOWN/XENKBD_MT_EV_MOTION events.
 441 *         0                1                 2               3        octet
 442 * +----------------+----------------+----------------+----------------+
 443 * |  _TYPE_MTOUCH  |  _MT_EV_SHAPE  |   contact_id   |    reserved    | 4
 444 * +----------------+----------------+----------------+----------------+
 445 * |                             reserved                              | 8
 446 * +----------------+----------------+----------------+----------------+
 447 * |                               major                               | 12
 448 * +----------------+----------------+----------------+----------------+
 449 * |                               minor                               | 16
 450 * +----------------+----------------+----------------+----------------+
 451 * |                             reserved                              | 20
 452 * +----------------+----------------+----------------+----------------+
 453 * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
 454 * +----------------+----------------+----------------+----------------+
 455 * |                             reserved                              | 40
 456 * +----------------+----------------+----------------+----------------+
 457 *
 458 * major - unt32_t, length of the major axis, pixels
 459 * minor - unt32_t, length of the minor axis, pixels
 460 *
 461 * Multi-touch orientation event - touch point's shape has changed
 462 * its orientation: calculated as a clockwise angle between the major axis
 463 * of the ellipse and positive Y axis in degrees, [-180; +180].
 464 *         0                1                 2               3        octet
 465 * +----------------+----------------+----------------+----------------+
 466 * |  _TYPE_MTOUCH  |  _MT_EV_ORIENT |   contact_id   |    reserved    | 4
 467 * +----------------+----------------+----------------+----------------+
 468 * |                             reserved                              | 8
 469 * +----------------+----------------+----------------+----------------+
 470 * |           orientation           |            reserved             | 12
 471 * +----------------+----------------+----------------+----------------+
 472 * |                             reserved                              | 16
 473 * +----------------+----------------+----------------+----------------+
 474 * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
 475 * +----------------+----------------+----------------+----------------+
 476 * |                             reserved                              | 40
 477 * +----------------+----------------+----------------+----------------+
 478 *
 479 * orientation - int16_t, clockwise angle of the major axis
 480 */
 481
 482struct xenkbd_mtouch {
 483    uint8_t type;            /* XENKBD_TYPE_MTOUCH */
 484    uint8_t event_type;      /* XENKBD_MT_EV_??? */
 485    uint8_t contact_id;
 486    uint8_t reserved[5];     /* reserved for the future use */
 487    union {
 488        struct {
 489            int32_t abs_x;   /* absolute X position, pixels */
 490            int32_t abs_y;   /* absolute Y position, pixels */
 491        } pos;
 492        struct {
 493            uint32_t major;  /* length of the major axis, pixels */
 494            uint32_t minor;  /* length of the minor axis, pixels */
 495        } shape;
 496        int16_t orientation; /* clockwise angle of the major axis */
 497    } u;
 498};
 499
 500#define XENKBD_IN_EVENT_SIZE 40
 501
 502union xenkbd_in_event
 503{
 504    uint8_t type;
 505    struct xenkbd_motion motion;
 506    struct xenkbd_key key;
 507    struct xenkbd_position pos;
 508    struct xenkbd_mtouch mtouch;
 509    char pad[XENKBD_IN_EVENT_SIZE];
 510};
 511
 512/*
 513 *****************************************************************************
 514 *                            Frontend to backend events
 515 *****************************************************************************
 516 *
 517 * Out events may be sent only when requested by backend, and receipt
 518 * of an unknown out event is an error.
 519 * No out events currently defined.
 520
 521 * All event packets have the same length (40 octets)
 522 * All event packets have common header:
 523 *          0         octet
 524 * +-----------------+
 525 * |       type      |
 526 * +-----------------+
 527 * type - uint8_t, event code
 528 */
 529
 530#define XENKBD_OUT_EVENT_SIZE 40
 531
 532union xenkbd_out_event
 533{
 534    uint8_t type;
 535    char pad[XENKBD_OUT_EVENT_SIZE];
 536};
 537
 538/*
 539 *****************************************************************************
 540 *                            Shared page
 541 *****************************************************************************
 542 */
 543
 544#define XENKBD_IN_RING_SIZE 2048
 545#define XENKBD_IN_RING_LEN (XENKBD_IN_RING_SIZE / XENKBD_IN_EVENT_SIZE)
 546#define XENKBD_IN_RING_OFFS 1024
 547#define XENKBD_IN_RING(page) \
 548    ((union xenkbd_in_event *)((char *)(page) + XENKBD_IN_RING_OFFS))
 549#define XENKBD_IN_RING_REF(page, idx) \
 550    (XENKBD_IN_RING((page))[(idx) % XENKBD_IN_RING_LEN])
 551
 552#define XENKBD_OUT_RING_SIZE 1024
 553#define XENKBD_OUT_RING_LEN (XENKBD_OUT_RING_SIZE / XENKBD_OUT_EVENT_SIZE)
 554#define XENKBD_OUT_RING_OFFS (XENKBD_IN_RING_OFFS + XENKBD_IN_RING_SIZE)
 555#define XENKBD_OUT_RING(page) \
 556    ((union xenkbd_out_event *)((char *)(page) + XENKBD_OUT_RING_OFFS))
 557#define XENKBD_OUT_RING_REF(page, idx) \
 558    (XENKBD_OUT_RING((page))[(idx) % XENKBD_OUT_RING_LEN])
 559
 560struct xenkbd_page
 561{
 562    uint32_t in_cons, in_prod;
 563    uint32_t out_cons, out_prod;
 564};
 565
 566#endif /* __XEN_PUBLIC_IO_KBDIF_H__ */
 567