diff options
Diffstat (limited to 'hw/kdrive')
-rw-r--r-- | hw/kdrive/ephyr/ephyr.c | 51 | ||||
-rw-r--r-- | hw/kdrive/ephyr/ephyrdriext.c | 24 | ||||
-rw-r--r-- | hw/kdrive/ephyr/ephyrdriext.h | 10 | ||||
-rw-r--r-- | hw/kdrive/ephyr/hostx.c | 54 | ||||
-rw-r--r-- | hw/kdrive/ephyr/hostx.h | 7 |
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, ®); + REGION_COPY (screen, ®, &pair->local->clipList); + screen->WindowExposures (pair->local, ®, NullRegion); + REGION_UNINIT (screen, ®); +} 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; |