xserver: Branch 'master' - 2 commits

Dodji Seketeli dodji at kemper.freedesktop.org
Thu Feb 21 06:33:05 PST 2008


 hw/kdrive/ephyr/ephyr.c        |   51 ++++++++++++++++++++++++++++++++++++--
 hw/kdrive/ephyr/ephyrdriext.c  |   24 +++++++++++++++---
 hw/kdrive/ephyr/ephyrdriext.h  |   10 +++++++
 hw/kdrive/ephyr/ephyrglxext.c  |   14 +++++++++-
 hw/kdrive/ephyr/ephyrhostglx.c |    9 +++++-
 hw/kdrive/ephyr/hostx.c        |   54 ++++++++++++++++++++++++++++++++++-------
 hw/kdrive/ephyr/hostx.h        |    7 ++++-
 7 files changed, 149 insertions(+), 20 deletions(-)

New commits:
commit c14fd2a5cb3f45d5c4502e09f55f5e3732c5e698
Author: Dodji Seketeli <dodji at seketeli.org>
Date:   Thu Feb 21 15:33:02 2008 +0100

    [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.

diff --git a/hw/kdrive/ephyr/ephyr.c b/hw/kdrive/ephyr/ephyr.c
index 6ec95d6..738704e 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 1b9dce5..fafe56d 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 66af833..01c9421 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 a5413b8..ae1bb4b 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 3caa466..f72cfe7 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;
commit 437c78ef9ff1177e04b3d6781b5805d89b2ab81a
Author: Dodji Seketeli <dodji at seketeli.org>
Date:   Thu Feb 21 15:29:27 2008 +0100

    [Xephyr/GL] don't crash when the host returns a NULL server string

diff --git a/hw/kdrive/ephyr/ephyrglxext.c b/hw/kdrive/ephyr/ephyrglxext.c
index 381c9d7..43a634d 100644
--- a/hw/kdrive/ephyr/ephyrglxext.c
+++ b/hw/kdrive/ephyr/ephyrglxext.c
@@ -362,7 +362,7 @@ ephyrGLXQueryServerString(__GLXclientState *a_cl, GLbyte *a_pc)
     ClientPtr client = a_cl->client;
     xGLXQueryServerStringReq *req = (xGLXQueryServerStringReq *) a_pc;
     xGLXQueryServerStringReply reply;
-    char *server_string=NULL ;
+    char *server_string=NULL, *buf=NULL;
     int length=0 ;
 
     EPHYR_LOG ("enter\n") ;
@@ -379,9 +379,15 @@ ephyrGLXQueryServerString(__GLXclientState *a_cl, GLbyte *a_pc)
     reply.sequenceNumber = client->sequence ;
     reply.length = __GLX_PAD (length) >> 2 ;
     reply.n = length ;
+    buf = xcalloc (reply.length << 2, 1);
+    if (!buf) {
+        EPHYR_LOG_ERROR ("failed to allocate string\n;");
+        return BadAlloc;
+    }
+    memcpy (buf, server_string, length);
 
     WriteToClient(client, sz_xGLXQueryServerStringReply, (char*)&reply);
-    WriteToClient(client, (int)length, server_string);
+    WriteToClient(client, (int)(reply.length << 2), server_string);
 
     res = Success ;
 
@@ -391,6 +397,10 @@ out:
         xfree (server_string) ;
         server_string = NULL;
     }
+    if (buf) {
+        xfree (buf);
+        buf = NULL;
+    }
     return res ;
 }
 
diff --git a/hw/kdrive/ephyr/ephyrhostglx.c b/hw/kdrive/ephyr/ephyrhostglx.c
index 5d9a482..f5db5be 100644
--- a/hw/kdrive/ephyr/ephyrhostglx.c
+++ b/hw/kdrive/ephyr/ephyrhostglx.c
@@ -151,6 +151,7 @@ ephyrHostGLXGetStringFromServer (int a_screen_number,
 {
     Bool is_ok=FALSE ;
     Display *dpy = hostx_get_display () ;
+    int default_screen = DefaultScreen (dpy);
     xGLXGenericGetStringReq *req=NULL;
     xGLXSingleReply reply;
     int length=0, numbytes=0, major_opcode=0, get_string_op=0;
@@ -188,13 +189,17 @@ ephyrHostGLXGetStringFromServer (int a_screen_number,
     GetReq (GLXGenericGetString, req);
     req->reqType = major_opcode;
     req->glxCode = get_string_op;
-    req->for_whom = DefaultScreen (dpy);
+    req->for_whom = default_screen;
     req->name = a_string_name;
 
     _XReply (dpy, (xReply *)&reply, 0, False);
 
     length = reply.length * 4;
-    numbytes = reply.size;
+    if (!length) {
+        numbytes = 0;
+    } else {
+        numbytes = reply.size;
+    }
     EPHYR_LOG ("going to get a string of size:%d\n", numbytes) ;
 
     *a_string = (char *) Xmalloc (numbytes +1);


More information about the xorg-commit mailing list