summaryrefslogtreecommitdiff
path: root/hw/kdrive/ephyr/ephyr.c
diff options
context:
space:
mode:
authorDodji Seketeli <dodji@seketeli.org>2008-02-21 15:33:02 +0100
committerDodji Seketeli <dodji@seketeli.org>2008-02-21 15:33:02 +0100
commitc14fd2a5cb3f45d5c4502e09f55f5e3732c5e698 (patch)
tree3a2078d6823a3131ea6a6fbea9d73a267f64d2d8 /hw/kdrive/ephyr/ephyr.c
parent437c78ef9ff1177e04b3d6781b5805d89b2ab81a (diff)
[Xephyr/GL] properly route expose event on GL drawables
When an expose event happens on an host GL window paired with an internal drawable, route that expose event to the clients listening to the expose event on the internal drawable.
Diffstat (limited to 'hw/kdrive/ephyr/ephyr.c')
-rw-r--r--hw/kdrive/ephyr/ephyr.c51
1 files changed, 48 insertions, 3 deletions
diff --git a/hw/kdrive/ephyr/ephyr.c b/hw/kdrive/ephyr/ephyr.c
index 6ec95d631..738704e40 100644
--- a/hw/kdrive/ephyr/ephyr.c
+++ b/hw/kdrive/ephyr/ephyr.c
@@ -841,6 +841,37 @@ miPointerScreenFuncRec ephyrPointerScreenFuncs =
ephyrWarpCursor
};
+/**
+ * find if the remote window denoted by a_remote
+ * is paired with an internal Window within the Xephyr server.
+ * If the remove window is paired with an internal window, send an
+ * expose event to the client insterested in the internal window expose event.
+ *
+ * Pairing happens when a drawable inside Xephyr is associated with
+ * a GL surface in a DRI environment.
+ * Look at the function ProcXF86DRICreateDrawable in ephyrdriext.c to
+ * know a paired window is created.
+ *
+ * This is useful to make GL drawables (only windows for now) handle
+ * expose events and send those events to clients.
+ */
+static void
+ephyrExposePairedWindow (int a_remote)
+{
+ EphyrWindowPair *pair = NULL;
+ RegionRec reg;
+ ScreenPtr screen;
+
+ if (!findWindowPairFromRemote (a_remote, &pair)) {
+ EPHYR_LOG ("did not find a pair for this window\n");
+ return;
+ }
+ screen = pair->local->drawable.pScreen;
+ REGION_NULL (screen, &reg);
+ REGION_COPY (screen, &reg, &pair->local->clipList);
+ screen->WindowExposures (pair->local, &reg, NullRegion);
+ REGION_UNINIT (screen, &reg);
+}
void
ephyrPoll(void)
@@ -861,9 +892,13 @@ ephyrPoll(void)
if (ephyrCurScreen != ev.data.mouse_motion.screen)
{
EPHYR_LOG ("warping mouse cursor:%d\n", ephyrCurScreen) ;
- ephyrWarpCursor(screenInfo.screens[ev.data.mouse_motion.screen],
- ev.data.mouse_motion.x,
- ev.data.mouse_motion.y );
+ if (ev.data.mouse_motion.screen >= 0)
+ {
+ ephyrWarpCursor
+ (screenInfo.screens[ev.data.mouse_motion.screen],
+ ev.data.mouse_motion.x,
+ ev.data.mouse_motion.y );
+ }
}
else
{
@@ -913,6 +948,16 @@ ephyrPoll(void)
KdEnqueueKeyboardEvent (ephyrKbd, ev.data.key_up.scancode, TRUE);
break;
+ case EPHYR_EV_EXPOSE:
+ /*
+ * We only receive expose events when the expose event have
+ * be generated for a drawable that is a host X window managed
+ * by Xephyr. Host X windows managed by Xephyr exists for instance
+ * when Xephyr is asked to create a GL drawable in a DRI environment.
+ */
+ ephyrExposePairedWindow (ev.data.expose.window);
+ break;
+
default:
break;
}