summaryrefslogtreecommitdiff
path: root/hw/kdrive/ephyr
diff options
context:
space:
mode:
Diffstat (limited to 'hw/kdrive/ephyr')
-rw-r--r--hw/kdrive/ephyr/ephyr.c51
-rw-r--r--hw/kdrive/ephyr/ephyrdriext.c24
-rw-r--r--hw/kdrive/ephyr/ephyrdriext.h10
-rw-r--r--hw/kdrive/ephyr/hostx.c54
-rw-r--r--hw/kdrive/ephyr/hostx.h7
5 files changed, 130 insertions, 16 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;
}
diff --git a/hw/kdrive/ephyr/ephyrdriext.c b/hw/kdrive/ephyr/ephyrdriext.c
index 1b9dce5c8..fafe56d1f 100644
--- a/hw/kdrive/ephyr/ephyrdriext.c
+++ b/hw/kdrive/ephyr/ephyrdriext.c
@@ -59,10 +59,6 @@
#define _HAVE_XALLOC_DECLS
#include "ephyrlog.h"
-typedef struct {
- WindowPtr local ;
- int remote ;
-} EphyrWindowPair;
typedef struct {
int foo;
@@ -950,6 +946,26 @@ findWindowPairFromLocal (WindowPtr a_local,
return FALSE ;
}
+Bool
+findWindowPairFromRemote (int a_remote,
+ EphyrWindowPair **a_pair)
+{
+ int i=0 ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_pair, FALSE) ;
+
+ for (i=0; i < NUM_WINDOW_PAIRS; i++) {
+ if (window_pairs[i].remote == a_remote) {
+ *a_pair = &window_pairs[i] ;
+ EPHYR_LOG ("found (%p, %d)\n",
+ (*a_pair)->local,
+ (*a_pair)->remote) ;
+ return TRUE ;
+ }
+ }
+ return FALSE ;
+}
+
static Bool
createHostPeerWindow (const WindowPtr a_win,
int *a_peer_win)
diff --git a/hw/kdrive/ephyr/ephyrdriext.h b/hw/kdrive/ephyr/ephyrdriext.h
index 66af833b9..01c9421fb 100644
--- a/hw/kdrive/ephyr/ephyrdriext.h
+++ b/hw/kdrive/ephyr/ephyrdriext.h
@@ -27,6 +27,16 @@
*/
#ifndef __EPHYRDRIEXT_H__
#define __EPHYRDRIEXT_H__
+
+typedef struct {
+ WindowPtr local ;
+ int remote ;
+} EphyrWindowPair;
+
Bool ephyrDRIExtensionInit (ScreenPtr a_screen) ;
+
+Bool findWindowPairFromRemote (int a_remote,
+ EphyrWindowPair **a_pair);
+
#endif /*__EPHYRDRIEXT_H__*/
diff --git a/hw/kdrive/ephyr/hostx.c b/hw/kdrive/ephyr/hostx.c
index a5413b876..ae1bb4bf9 100644
--- a/hw/kdrive/ephyr/hostx.c
+++ b/hw/kdrive/ephyr/hostx.c
@@ -839,16 +839,38 @@ hostx_load_keymap(void)
static struct EphyrHostScreen *
host_screen_from_window (Window w)
{
- int index;
+ int index = 0;
+ struct EphyrHostScreen *result = NULL;
+#if 0
+ unsigned int num_children = 0;
+ Window root = None, parent = None, *children = NULL;
+#endif
for (index = 0 ; index < HostX.n_screens ; index++)
{
if (HostX.screens[index].win == w)
{
- return &HostX.screens[index];
+ result = &HostX.screens[index];
+ goto out;
}
}
- return NULL;
+#if 0
+ XQueryTree (hostx_get_display (), w, &root, &parent,
+ &children, &num_children);
+ if (parent == root || parent == None)
+ goto out;
+ result = host_screen_from_window (parent);
+#endif
+
+out:
+#if 0
+ if (children)
+ {
+ XFree (children);
+ children = NULL;
+ }
+#endif
+ return result;
}
int
@@ -870,9 +892,19 @@ hostx_get_event(EphyrHostXEvent *ev)
{
struct EphyrHostScreen *host_screen =
host_screen_from_window (xev.xexpose.window);
- hostx_paint_rect (host_screen->info, 0, 0, 0, 0,
- host_screen->win_width,
- host_screen->win_height);
+ if (host_screen)
+ {
+ hostx_paint_rect (host_screen->info, 0, 0, 0, 0,
+ host_screen->win_width,
+ host_screen->win_height);
+ }
+ else
+ {
+ EPHYR_LOG_ERROR ("failed to get host screen\n");
+ ev->type = EPHYR_EV_EXPOSE;
+ ev->data.expose.window = xev.xexpose.window;
+ return 1;
+ }
}
return 0;
@@ -1113,12 +1145,18 @@ hostx_create_window (int a_screen_number,
visual_info->screen),
visual_info->visual,
AllocNone) ;
- winmask = CWColormap;
+ attrs.event_mask = ButtonPressMask
+ |ButtonReleaseMask
+ |PointerMotionMask
+ |KeyPressMask
+ |KeyReleaseMask
+ |ExposureMask;
+ winmask = CWColormap|CWEventMask;
win = XCreateWindow (dpy, hostx_get_window (a_screen_number),
a_geometry->x, a_geometry->y,
a_geometry->width, a_geometry->height, 0,
- visual_info->depth, InputOutput,
+ visual_info->depth, CopyFromParent,
visual_info->visual, winmask, &attrs) ;
if (win == None) {
EPHYR_LOG_ERROR ("failed to create peer window\n") ;
diff --git a/hw/kdrive/ephyr/hostx.h b/hw/kdrive/ephyr/hostx.h
index 3caa466a7..f72cfe700 100644
--- a/hw/kdrive/ephyr/hostx.h
+++ b/hw/kdrive/ephyr/hostx.h
@@ -47,7 +47,8 @@ typedef enum EphyrHostXEventType
EPHYR_EV_MOUSE_PRESS,
EPHYR_EV_MOUSE_RELEASE,
EPHYR_EV_KEY_PRESS,
- EPHYR_EV_KEY_RELEASE
+ EPHYR_EV_KEY_RELEASE,
+ EPHYR_EV_EXPOSE
}
EphyrHostXEventType;
@@ -87,6 +88,10 @@ struct EphyrHostXEvent
int scancode;
} key_down;
+ struct expose {
+ int window;
+ } expose;
+
} data;
int key_state;