aboutsummaryrefslogtreecommitdiff
path: root/xorg-server/include
diff options
context:
space:
mode:
Diffstat (limited to 'xorg-server/include')
-rw-r--r--xorg-server/include/dix.h4
-rw-r--r--xorg-server/include/eventstr.h488
-rw-r--r--xorg-server/include/input.h50
-rw-r--r--xorg-server/include/inputstr.h10
-rw-r--r--xorg-server/include/inpututils.h2
-rw-r--r--xorg-server/include/misc.h18
6 files changed, 303 insertions, 269 deletions
diff --git a/xorg-server/include/dix.h b/xorg-server/include/dix.h
index de78b7e24..daac63a2e 100644
--- a/xorg-server/include/dix.h
+++ b/xorg-server/include/dix.h
@@ -375,7 +375,7 @@ extern void ReleaseActiveGrabs(
extern GrabPtr CheckPassiveGrabsOnWindow(
WindowPtr /* pWin */,
DeviceIntPtr /* device */,
- DeviceEvent * /* event */,
+ InternalEvent * /* event */,
BOOL /* checkCore */,
BOOL /* activate */);
@@ -415,7 +415,7 @@ extern void DeliverFocusedEvent(
InternalEvent* /* event */,
WindowPtr /* window */);
-extern void DeliverGrabbedEvent(
+extern int DeliverGrabbedEvent(
InternalEvent* /* event */,
DeviceIntPtr /* thisDev */,
Bool /* deactivateGrab */);
diff --git a/xorg-server/include/eventstr.h b/xorg-server/include/eventstr.h
index 673207ce3..83f96d168 100644
--- a/xorg-server/include/eventstr.h
+++ b/xorg-server/include/eventstr.h
@@ -1,246 +1,242 @@
-/*
- * Copyright © 2009 Red Hat, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- */
-
-#ifndef EVENTSTR_H
-#define EVENTSTR_H
-
-#include <events.h>
-/**
- * @file events.h
- * This file describes the event structures used internally by the X
- * server during event generation and event processing.
- *
- * When are internal events used?
- * Events from input devices are stored as internal events in the EQ and
- * processed as internal events until late in the processing cycle. Only then
- * do they switch to their respective wire events.
- */
-
-/**
- * Event types. Used exclusively internal to the server, not visible on the
- * protocol.
- *
- * Note: Keep KeyPress to Motion aligned with the core events.
- * Keep ET_Raw* in the same order as KeyPress - Motion
- */
-enum EventType {
- ET_KeyPress = 2,
- ET_KeyRelease,
- ET_ButtonPress,
- ET_ButtonRelease,
- ET_Motion,
- ET_Enter,
- ET_Leave,
- ET_FocusIn,
- ET_FocusOut,
- ET_ProximityIn,
- ET_ProximityOut,
- ET_DeviceChanged,
- ET_Hierarchy,
- ET_DGAEvent,
- ET_RawKeyPress,
- ET_RawKeyRelease,
- ET_RawButtonPress,
- ET_RawButtonRelease,
- ET_RawMotion,
- ET_XQuartz,
- ET_Internal = 0xFF /* First byte */
-};
-
-#define CHECKEVENT(ev) if (ev && ((InternalEvent*)(ev))->any.header != 0xFF) \
- FatalError("Wrong event type %d.\n", \
- ((InternalEvent*)(ev))->any.header);
-
-/**
- * Used for ALL input device events internal in the server until
- * copied into the matching protocol event.
- *
- * Note: We only use the device id because the DeviceIntPtr may become invalid while
- * the event is in the EQ.
- */
-struct _DeviceEvent
-{
- unsigned char header; /**< Always ET_Internal */
- enum EventType type; /**< One of EventType */
- int length; /**< Length in bytes */
- Time time; /**< Time in ms */
- int deviceid; /**< Device to post this event for */
- int sourceid; /**< The physical source device */
- union {
- uint32_t button; /**< Button number */
- uint32_t key; /**< Key code */
- } detail;
- int16_t root_x; /**< Pos relative to root window in integral data */
- float root_x_frac; /**< Pos relative to root window in frac part */
- int16_t root_y; /**< Pos relative to root window in integral part */
- float root_y_frac; /**< Pos relative to root window in frac part */
- uint8_t buttons[(MAX_BUTTONS + 7)/8]; /**< Button mask */
- struct {
- uint8_t mask[(MAX_VALUATORS + 7)/8]; /**< Valuator mask */
- uint8_t mode[(MAX_VALUATORS + 7)/8]; /**< Valuator mode (Abs or Rel)*/
- int32_t data[MAX_VALUATORS]; /**< Valuator data */
- int32_t data_frac[MAX_VALUATORS]; /**< Fractional part for data */
- } valuators;
- struct {
- uint32_t base; /**< XKB base modifiers */
- uint32_t latched; /**< XKB latched modifiers */
- uint32_t locked; /**< XKB locked modifiers */
- uint32_t effective;/**< XKB effective modifiers */
- } mods;
- struct {
- uint8_t base; /**< XKB base group */
- uint8_t latched; /**< XKB latched group */
- uint8_t locked; /**< XKB locked group */
- uint8_t effective;/**< XKB effective group */
- } group;
- Window root; /**< Root window of the event */
- int corestate; /**< Core key/button state BEFORE the event */
- int key_repeat; /**< Internally-generated key repeat event */
-};
-
-
-/* Flags used in DeviceChangedEvent to signal if the slave has changed */
-#define DEVCHANGE_SLAVE_SWITCH 0x2
-/* Flags used in DeviceChangedEvent to signal whether the event was a
- * pointer event or a keyboard event */
-#define DEVCHANGE_POINTER_EVENT 0x4
-#define DEVCHANGE_KEYBOARD_EVENT 0x8
-/* device capabilities changed */
-#define DEVCHANGE_DEVICE_CHANGE 0x10
-
-/**
- * Sent whenever a device's capabilities have changed.
- */
-struct _DeviceChangedEvent
-{
- unsigned char header; /**< Always ET_Internal */
- enum EventType type; /**< ET_DeviceChanged */
- int length; /**< Length in bytes */
- Time time; /**< Time in ms */
- int deviceid; /**< Device whose capabilities have changed */
- int flags; /**< Mask of ::HAS_NEW_SLAVE,
- ::POINTER_EVENT, ::KEYBOARD_EVENT */
- int masterid; /**< MD when event was generated */
- int sourceid; /**< The device that caused the change */
-
- struct {
- int num_buttons; /**< Number of buttons */
- Atom names[MAX_BUTTONS];/**< Button names */
- } buttons;
-
- int num_valuators; /**< Number of axes */
- struct {
- uint32_t min; /**< Minimum value */
- uint32_t max; /**< Maximum value */
- /* FIXME: frac parts of min/max */
- uint32_t resolution; /**< Resolution counts/m */
- uint8_t mode; /**< Relative or Absolute */
- Atom name; /**< Axis name */
- } valuators[MAX_VALUATORS];
-
- struct {
- int min_keycode;
- int max_keycode;
- } keys;
-};
-
-#if XFreeXDGA
-/**
- * DGAEvent, used by DGA to intercept and emulate input events.
- */
-struct _DGAEvent
-{
- unsigned char header; /**< Always ET_Internal */
- enum EventType type; /**< ET_DGAEvent */
- int length; /**< Length in bytes */
- Time time; /**< Time in ms */
- int subtype; /**< KeyPress, KeyRelease, ButtonPress,
- ButtonRelease, MotionNotify */
- int detail; /**< Button number or key code */
- int dx; /**< Relative x coordinate */
- int dy; /**< Relative y coordinate */
- int screen; /**< Screen number this event applies to */
- uint16_t state; /**< Core modifier/button state */
-};
-#endif
-
-/**
- * Raw event, contains the data as posted by the device.
- */
-struct _RawDeviceEvent
-{
- unsigned char header; /**< Always ET_Internal */
- enum EventType type; /**< ET_Raw */
- int length; /**< Length in bytes */
- Time time; /**< Time in ms */
- int deviceid; /**< Device to post this event for */
- int sourceid; /**< The physical source device */
- union {
- uint32_t button; /**< Button number */
- uint32_t key; /**< Key code */
- } detail;
- struct {
- uint8_t mask[(MAX_VALUATORS + 7)/8]; /**< Valuator mask */
- int32_t data[MAX_VALUATORS]; /**< Valuator data */
- int32_t data_frac[MAX_VALUATORS]; /**< Fractional part for data */
- int32_t data_raw[MAX_VALUATORS]; /**< Valuator data as posted */
- int32_t data_raw_frac[MAX_VALUATORS];/**< Fractional part for data_raw */
- } valuators;
-};
-
-#ifdef XQUARTZ
-#define XQUARTZ_EVENT_MAXARGS 5
-struct _XQuartzEvent {
- unsigned char header; /**< Always ET_Internal */
- enum EventType type; /**< Always ET_XQuartz */
- int length; /**< Length in bytes */
- Time time; /**< Time in ms. */
- int subtype; /**< Subtype defined by XQuartz DDX */
- uint32_t data[XQUARTZ_EVENT_MAXARGS]; /**< Up to 5 32bit values passed to handler */
-};
-#endif
-
-/**
- * Event type used inside the X server for input event
- * processing.
- */
-union _InternalEvent {
- struct {
- unsigned char header; /**< Always ET_Internal */
- enum EventType type; /**< One of ET_* */
- int length; /**< Length in bytes */
- Time time; /**< Time in ms. */
- } any;
- DeviceEvent device_event;
- DeviceChangedEvent changed_event;
-#if XFreeXDGA
- DGAEvent dga_event;
-#endif
- RawDeviceEvent raw_event;
-#ifdef XQUARTZ
- XQuartzEvent xquartz_event;
-#endif
-};
-
-#endif
+/*
+ * Copyright © 2009 Red Hat, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#ifndef EVENTSTR_H
+#define EVENTSTR_H
+
+#include <events.h>
+/**
+ * @file events.h
+ * This file describes the event structures used internally by the X
+ * server during event generation and event processing.
+ *
+ * When are internal events used?
+ * Events from input devices are stored as internal events in the EQ and
+ * processed as internal events until late in the processing cycle. Only then
+ * do they switch to their respective wire events.
+ */
+
+/**
+ * Event types. Used exclusively internal to the server, not visible on the
+ * protocol.
+ *
+ * Note: Keep KeyPress to Motion aligned with the core events.
+ * Keep ET_Raw* in the same order as KeyPress - Motion
+ */
+enum EventType {
+ ET_KeyPress = 2,
+ ET_KeyRelease,
+ ET_ButtonPress,
+ ET_ButtonRelease,
+ ET_Motion,
+ ET_Enter,
+ ET_Leave,
+ ET_FocusIn,
+ ET_FocusOut,
+ ET_ProximityIn,
+ ET_ProximityOut,
+ ET_DeviceChanged,
+ ET_Hierarchy,
+ ET_DGAEvent,
+ ET_RawKeyPress,
+ ET_RawKeyRelease,
+ ET_RawButtonPress,
+ ET_RawButtonRelease,
+ ET_RawMotion,
+ ET_XQuartz,
+ ET_Internal = 0xFF /* First byte */
+};
+
+/**
+ * Used for ALL input device events internal in the server until
+ * copied into the matching protocol event.
+ *
+ * Note: We only use the device id because the DeviceIntPtr may become invalid while
+ * the event is in the EQ.
+ */
+struct _DeviceEvent
+{
+ unsigned char header; /**< Always ET_Internal */
+ enum EventType type; /**< One of EventType */
+ int length; /**< Length in bytes */
+ Time time; /**< Time in ms */
+ int deviceid; /**< Device to post this event for */
+ int sourceid; /**< The physical source device */
+ union {
+ uint32_t button; /**< Button number */
+ uint32_t key; /**< Key code */
+ } detail;
+ int16_t root_x; /**< Pos relative to root window in integral data */
+ float root_x_frac; /**< Pos relative to root window in frac part */
+ int16_t root_y; /**< Pos relative to root window in integral part */
+ float root_y_frac; /**< Pos relative to root window in frac part */
+ uint8_t buttons[(MAX_BUTTONS + 7)/8]; /**< Button mask */
+ struct {
+ uint8_t mask[(MAX_VALUATORS + 7)/8]; /**< Valuator mask */
+ uint8_t mode[(MAX_VALUATORS + 7)/8]; /**< Valuator mode (Abs or Rel)*/
+ int32_t data[MAX_VALUATORS]; /**< Valuator data */
+ int32_t data_frac[MAX_VALUATORS]; /**< Fractional part for data */
+ } valuators;
+ struct {
+ uint32_t base; /**< XKB base modifiers */
+ uint32_t latched; /**< XKB latched modifiers */
+ uint32_t locked; /**< XKB locked modifiers */
+ uint32_t effective;/**< XKB effective modifiers */
+ } mods;
+ struct {
+ uint8_t base; /**< XKB base group */
+ uint8_t latched; /**< XKB latched group */
+ uint8_t locked; /**< XKB locked group */
+ uint8_t effective;/**< XKB effective group */
+ } group;
+ Window root; /**< Root window of the event */
+ int corestate; /**< Core key/button state BEFORE the event */
+ int key_repeat; /**< Internally-generated key repeat event */
+};
+
+
+/* Flags used in DeviceChangedEvent to signal if the slave has changed */
+#define DEVCHANGE_SLAVE_SWITCH 0x2
+/* Flags used in DeviceChangedEvent to signal whether the event was a
+ * pointer event or a keyboard event */
+#define DEVCHANGE_POINTER_EVENT 0x4
+#define DEVCHANGE_KEYBOARD_EVENT 0x8
+/* device capabilities changed */
+#define DEVCHANGE_DEVICE_CHANGE 0x10
+
+/**
+ * Sent whenever a device's capabilities have changed.
+ */
+struct _DeviceChangedEvent
+{
+ unsigned char header; /**< Always ET_Internal */
+ enum EventType type; /**< ET_DeviceChanged */
+ int length; /**< Length in bytes */
+ Time time; /**< Time in ms */
+ int deviceid; /**< Device whose capabilities have changed */
+ int flags; /**< Mask of ::HAS_NEW_SLAVE,
+ ::POINTER_EVENT, ::KEYBOARD_EVENT */
+ int masterid; /**< MD when event was generated */
+ int sourceid; /**< The device that caused the change */
+
+ struct {
+ int num_buttons; /**< Number of buttons */
+ Atom names[MAX_BUTTONS];/**< Button names */
+ } buttons;
+
+ int num_valuators; /**< Number of axes */
+ struct {
+ uint32_t min; /**< Minimum value */
+ uint32_t max; /**< Maximum value */
+ /* FIXME: frac parts of min/max */
+ uint32_t resolution; /**< Resolution counts/m */
+ uint8_t mode; /**< Relative or Absolute */
+ Atom name; /**< Axis name */
+ } valuators[MAX_VALUATORS];
+
+ struct {
+ int min_keycode;
+ int max_keycode;
+ } keys;
+};
+
+#if XFreeXDGA
+/**
+ * DGAEvent, used by DGA to intercept and emulate input events.
+ */
+struct _DGAEvent
+{
+ unsigned char header; /**< Always ET_Internal */
+ enum EventType type; /**< ET_DGAEvent */
+ int length; /**< Length in bytes */
+ Time time; /**< Time in ms */
+ int subtype; /**< KeyPress, KeyRelease, ButtonPress,
+ ButtonRelease, MotionNotify */
+ int detail; /**< Button number or key code */
+ int dx; /**< Relative x coordinate */
+ int dy; /**< Relative y coordinate */
+ int screen; /**< Screen number this event applies to */
+ uint16_t state; /**< Core modifier/button state */
+};
+#endif
+
+/**
+ * Raw event, contains the data as posted by the device.
+ */
+struct _RawDeviceEvent
+{
+ unsigned char header; /**< Always ET_Internal */
+ enum EventType type; /**< ET_Raw */
+ int length; /**< Length in bytes */
+ Time time; /**< Time in ms */
+ int deviceid; /**< Device to post this event for */
+ int sourceid; /**< The physical source device */
+ union {
+ uint32_t button; /**< Button number */
+ uint32_t key; /**< Key code */
+ } detail;
+ struct {
+ uint8_t mask[(MAX_VALUATORS + 7)/8]; /**< Valuator mask */
+ int32_t data[MAX_VALUATORS]; /**< Valuator data */
+ int32_t data_frac[MAX_VALUATORS]; /**< Fractional part for data */
+ int32_t data_raw[MAX_VALUATORS]; /**< Valuator data as posted */
+ int32_t data_raw_frac[MAX_VALUATORS];/**< Fractional part for data_raw */
+ } valuators;
+};
+
+#ifdef XQUARTZ
+#define XQUARTZ_EVENT_MAXARGS 5
+struct _XQuartzEvent {
+ unsigned char header; /**< Always ET_Internal */
+ enum EventType type; /**< Always ET_XQuartz */
+ int length; /**< Length in bytes */
+ Time time; /**< Time in ms. */
+ int subtype; /**< Subtype defined by XQuartz DDX */
+ uint32_t data[XQUARTZ_EVENT_MAXARGS]; /**< Up to 5 32bit values passed to handler */
+};
+#endif
+
+/**
+ * Event type used inside the X server for input event
+ * processing.
+ */
+union _InternalEvent {
+ struct {
+ unsigned char header; /**< Always ET_Internal */
+ enum EventType type; /**< One of ET_* */
+ int length; /**< Length in bytes */
+ Time time; /**< Time in ms. */
+ } any;
+ DeviceEvent device_event;
+ DeviceChangedEvent changed_event;
+#if XFreeXDGA
+ DGAEvent dga_event;
+#endif
+ RawDeviceEvent raw_event;
+#ifdef XQUARTZ
+ XQuartzEvent xquartz_event;
+#endif
+};
+
+#endif
diff --git a/xorg-server/include/input.h b/xorg-server/include/input.h
index 2aa5dbb74..13f4ba98e 100644
--- a/xorg-server/include/input.h
+++ b/xorg-server/include/input.h
@@ -109,19 +109,8 @@ typedef union _GrabMask GrabMask;
typedef struct _ValuatorMask ValuatorMask;
-typedef struct _EventList {
- xEvent* event;
- int evlen; /* length of allocated memory for event in bytes. This is not
- the actual length of the event. The event's actual length is
- 32 for standard events or 32 +
- ((xGenericEvent*)event)->length * 4 for GenericEvents.
- For events in the EQ, the length is
- ((InternalEvent*)event)->u.any.length */
-} EventList, *EventListPtr;
-
/* The DIX stores incoming input events in this list */
-extern EventListPtr InputEventList;
-extern int InputEventListLen;
+extern InternalEvent* InputEventList;
typedef int (*DeviceProc)(
DeviceIntPtr /*device*/,
@@ -439,22 +428,28 @@ extern _X_EXPORT void CloseInput(void);
extern _X_EXPORT int GetMaximumEventsNum(void);
-extern _X_EXPORT int GetEventList(EventListPtr* list);
-extern _X_EXPORT EventListPtr InitEventList(int num_events);
-extern _X_EXPORT void FreeEventList(EventListPtr list, int num_events);
+extern _X_EXPORT InternalEvent *InitEventList(int num_events);
+extern _X_EXPORT void FreeEventList(InternalEvent *list, int num_events);
-extern void CreateClassesChangedEvent(EventListPtr event,
+extern void CreateClassesChangedEvent(InternalEvent *event,
DeviceIntPtr master,
DeviceIntPtr slave,
int type);
-extern EventListPtr UpdateFromMaster(
- EventListPtr events,
+extern InternalEvent * UpdateFromMaster(
+ InternalEvent *events,
DeviceIntPtr pDev,
int type,
int *num_events);
extern _X_EXPORT int GetPointerEvents(
- EventListPtr events,
+ InternalEvent *events,
+ DeviceIntPtr pDev,
+ int type,
+ int buttons,
+ int flags,
+ const ValuatorMask *mask);
+
+extern _X_EXPORT void QueuePointerEvents(
DeviceIntPtr pDev,
int type,
int buttons,
@@ -462,14 +457,25 @@ extern _X_EXPORT int GetPointerEvents(
const ValuatorMask *mask);
extern _X_EXPORT int GetKeyboardEvents(
- EventListPtr events,
+ InternalEvent *events,
+ DeviceIntPtr pDev,
+ int type,
+ int key_code,
+ const ValuatorMask *mask);
+
+extern _X_EXPORT void QueueKeyboardEvents(
DeviceIntPtr pDev,
int type,
int key_code,
const ValuatorMask *mask);
extern int GetProximityEvents(
- EventListPtr events,
+ InternalEvent *events,
+ DeviceIntPtr pDev,
+ int type,
+ const ValuatorMask *mask);
+
+extern void QueueProximityEvents(
DeviceIntPtr pDev,
int type,
const ValuatorMask *mask);
@@ -495,6 +501,8 @@ extern _X_EXPORT int GetMotionHistory(
ScreenPtr pScreen,
BOOL core);
+extern void ReleaseButtonsAndKeys(DeviceIntPtr dev);
+
extern int AttachDevice(ClientPtr client,
DeviceIntPtr slave,
DeviceIntPtr master);
diff --git a/xorg-server/include/inputstr.h b/xorg-server/include/inputstr.h
index 80e8ad8c7..ecbc6e09e 100644
--- a/xorg-server/include/inputstr.h
+++ b/xorg-server/include/inputstr.h
@@ -591,4 +591,14 @@ typedef struct _EventSyncInfo {
extern EventSyncInfoRec syncEvents;
+/**
+ * Given a sprite, returns the window at the bottom of the trace (i.e. the
+ * furthest window from the root).
+ */
+static inline WindowPtr DeepestSpriteWin(SpritePtr sprite)
+{
+ assert(sprite->spriteTraceGood > 0);
+ return sprite->spriteTrace[sprite->spriteTraceGood - 1];
+}
+
#endif /* INPUTSTRUCT_H */
diff --git a/xorg-server/include/inpututils.h b/xorg-server/include/inpututils.h
index af07afeb0..0e8488af5 100644
--- a/xorg-server/include/inpututils.h
+++ b/xorg-server/include/inpututils.h
@@ -37,4 +37,6 @@ struct _ValuatorMask {
int valuators[MAX_VALUATORS]; /* valuator data */
};
+extern void verify_internal_event(const InternalEvent *ev);
+
#endif
diff --git a/xorg-server/include/misc.h b/xorg-server/include/misc.h
index 02790d38e..ba3776079 100644
--- a/xorg-server/include/misc.h
+++ b/xorg-server/include/misc.h
@@ -228,6 +228,24 @@ pad_to_int32(const int bytes) {
extern char**
xstrtokenize(const char *str, const char* separators);
+/**
+ * Compare the two version numbers comprising of major.minor.
+ *
+ * @return A value less than 0 if a is less than b, 0 if a is equal to b,
+ * or a value greater than 0
+ */
+static inline int
+version_compare(uint16_t a_major, uint16_t a_minor,
+ uint16_t b_major, uint16_t b_minor)
+{
+ int a, b;
+
+ a = a_major << 16 | a_minor;
+ b = b_major << 16 | b_minor;
+
+ return (a - b);
+}
+
/* some macros to help swap requests, replies, and events */
#define LengthRestB(stuff) \