diff -urN xorg-server-1.17.1-orig/Xext/geext.c xorg-server-1.17.1/Xext/geext.c
--- xorg-server-1.17.1-orig/Xext/geext.c	2014-02-05 12:08:57 +0900
+++ xorg-server-1.17.1/Xext/geext.c	2015-03-07 06:22:58 +0900
@@ -31,6 +31,9 @@
 
 #include "geint.h"
 #include "geext.h"
+#include "xace.h"
+#include "inputstr.h" /* SpritePtr */
+#include "exglobals.h" /* BadDevice */
 #include "protocol-versions.h"
 #include "extinit.h"
 
@@ -41,7 +44,8 @@
 /* Major available requests */
 static const int version_requests[] = {
     X_GEQueryVersion,           /* before client sends QueryVersion */
-    X_GEQueryVersion,           /* must be set to last request in version 1 */
+    X_GESendEvent,              /* send event, since 1.1 */
+    X_GESendEvent,              /* must be set to last request in version 1.1 */
 };
 
 /* Forward declarations */
@@ -90,9 +94,105 @@
     return Success;
 }
 
+static int
+ProcGESendEvent(ClientPtr client)
+{
+    WindowPtr pWin;
+    WindowPtr effectiveFocus = NullWindow; /* only set if dest==InputFocus */
+    DeviceIntPtr dev = PickPointer(client);
+    DeviceIntPtr keybd = GetPairedDevice(dev);
+    SpritePtr pSprite;
+    xGenericEvent *event;
+    REQUEST(xGESendEventReq);
+
+    REQUEST_AT_LEAST_SIZE(xGESendEventReq);
+
+    event = (xGenericEvent *) &stuff[1];
+
+    /* The client's event type must be a GenericEvent. */
+    if (event->type != GenericEvent) {
+        client->errorValue = event->type;
+        return BadValue;
+    }
+
+    dev = GetEventDevice(client, (xEvent *) event);
+
+    if (!dev)
+        return BadDevice;
+
+    if (IsPointerDevice (dev)) {
+        keybd = GetPairedDevice(dev);
+    } else {
+        keybd = dev;
+        dev = GetPairedDevice(keybd);
+    }
+
+    pSprite = dev->spriteInfo->sprite;
+
+    /* FIXME: Check for eventMask containing only the extension mask bits set on */
+
+    if (stuff->destination == PointerWindow)
+        pWin = pSprite->win;
+    else if (stuff->destination == InputFocus) {
+        WindowPtr inputFocus = (keybd) ? keybd->focus->win : NoneWin;
+
+        if (inputFocus == NoneWin)
+            return Success;
+
+        /* If the input focus is PointerRootWin, send the event to where
+           the pointer is if possible, then perhaps propogate up to root. */
+        if (inputFocus == PointerRootWin)
+            inputFocus = pSprite->spriteTrace[0]; /* Root window! */
+
+        if (IsParent(inputFocus, pSprite->win)) {
+            effectiveFocus = inputFocus;
+            pWin = pSprite->win;
+        } else {
+            effectiveFocus = pWin = inputFocus;
+        }
+    } else {
+        dixLookupWindow(&pWin, stuff->destination, client, DixSendAccess);
+    }
+
+    if (!pWin)
+        return BadWindow;
+
+    if ((stuff->propagate != xFalse) && (stuff->propagate != xTrue)) {
+        client->errorValue = stuff->propagate;
+        return BadValue;
+    }
+
+    if (stuff->propagate) {
+        for (;pWin; pWin = pWin->parent) {
+            if (XaceHook(XACE_SEND_ACCESS, client, NULL, pWin, event, 1))
+                return Success;
+
+            if (DeliverEventsToWindow(dev, pWin, (xEvent *) event,
+                                      1, stuff->eventMask, NullGrab))
+                return Success;
+
+            if (pWin == effectiveFocus)
+                return Success;
+
+            stuff->eventMask &= ~wDontPropagateMask(pWin);
+
+            if (!stuff->eventMask)
+                break;
+        }
+    } else if (!XaceHook(XACE_SEND_ACCESS, client, NULL, pWin, event, 1)) {
+        DeliverEventsToWindow(dev, pWin, (xEvent *) event,
+                              1, stuff->eventMask, NullGrab);
+    }
+
+    return Success;
+}
+
 int (*ProcGEVector[GENumberRequests]) (ClientPtr) = {
     /* Version 1.0 */
-ProcGEQueryVersion};
+    ProcGEQueryVersion,
+    /* Version 1.1 */
+    ProcGESendEvent
+};
 
 /************************************************************/
 /*                swapped request handlers                  */
@@ -109,9 +209,55 @@
     return (*ProcGEVector[stuff->ReqType]) (client);
 }
 
+static int
+SProcGESendEvent(ClientPtr client)
+{
+    xEvent *ev;
+    static void *swapEvent;
+    static int swapEventLen;
+    int len;
+
+    REQUEST(xGESendEventReq);
+
+    swaps(&stuff->length);
+    REQUEST_AT_LEAST_SIZE(xGESendEventReq);
+
+    ev = (xEvent *) &stuff[1];
+
+    if (ev->u.u.type != GenericEvent) {
+        client->errorValue = ev->u.u.type;
+        return BadValue;
+    }
+
+    /* Swap request fields */
+    swapl(&stuff->destination);
+    swapl(&stuff->eventMask);
+
+    /* Swap event being sent */
+    len = sizeof (xEvent) + (((xGenericEvent*) ev)->length << 2);
+
+    if (len > swapEventLen) {
+        swapEventLen = len;
+        swapEvent = realloc(swapEvent, swapEventLen);
+
+        if (!swapEvent) {
+            FatalError("SProcGESendEvent: Out of memory.\n");
+            return BadValue;
+        }
+    }
+
+    SGEGenericEvent(ev, swapEvent);
+    memcpy(ev, swapEvent, len);
+
+    return(*ProcGEVector[stuff->ReqType])(client);
+}
+
 int (*SProcGEVector[GENumberRequests]) (ClientPtr) = {
     /* Version 1.0 */
-SProcGEQueryVersion};
+    SProcGEQueryVersion,
+    /* Version 1.1 */
+    SProcGESendEvent
+};
 
 /************************************************************/
 /*                callbacks                                 */
diff -urN xorg-server-1.17.1-orig/dix/events.c xorg-server-1.17.1/dix/events.c
--- xorg-server-1.17.1-orig/dix/events.c	2014-07-18 03:16:51 +0900
+++ xorg-server-1.17.1/dix/events.c	2015-03-07 06:19:24 +0900
@@ -473,6 +473,27 @@
     return xi2mask_isset(inputMasks->xi2mask, dev, evtype);
 }
 
+DeviceIntPtr
+GetEventDevice(ClientPtr client, xEvent *ev)
+{
+    if (ev->u.u.type == GenericEvent &&
+        ((xGenericEvent *) ev)->extension == IReqCode) {
+        DeviceIntPtr pDev;
+        int rc;
+
+        rc = dixLookupDevice(&pDev,
+                             ((xXIGenericDeviceEvent *) ev)->deviceid,
+                             client, DixWriteAccess);
+
+        if (rc == Success)
+            return pDev;
+    } else {
+        return PickPointer (client);
+    }
+
+    return NULL;
+}
+
 Mask
 GetEventMask(DeviceIntPtr dev, xEvent *event, InputClients * other)
 {
diff -urN xorg-server-1.17.1-orig/include/input.h xorg-server-1.17.1/include/input.h
--- xorg-server-1.17.1-orig/include/input.h	2015-01-18 08:42:52 +0900
+++ xorg-server-1.17.1/include/input.h	2015-03-07 05:39:04 +0900
@@ -601,6 +601,7 @@
 extern Mask GetEventFilter(DeviceIntPtr dev, xEvent *event);
 extern Bool WindowXI2MaskIsset(DeviceIntPtr dev, WindowPtr win, xEvent *ev);
 extern int GetXI2MaskByte(XI2Mask *mask, DeviceIntPtr dev, int event_type);
+extern DeviceIntPtr GetEventDevice(ClientPtr client, xEvent* ev);
 void FixUpEventFromWindow(SpritePtr pSprite,
                           xEvent *xE,
                           WindowPtr pWin, Window child, Bool calcChild);
