Hi,

A while ago I made this patch to add a useful feature in Xephyr.
Currently when you embed Xephyr in another window, it initializes a
fixed size based on the parant. However, in many cases the parent window
want to resize on the fly... Xephyr turned out to behave badly when it
resizes. This patch solved the problem.

It was submitted in bugzilla:

http://bugs.freedesktop.org/show_bug.cgi?id=25804

I was suggested to post the patch in this list for review. Appreciate if
anyone in this list can help to review this patch and move it forward.

Thanks,

Vic
>From 3ba764fe134338552537bbc51686b26d4db3a122 Mon Sep 17 00:00:00 2001
From: Vic Lee <[email protected]>
Date: Sun, 27 Dec 2009 23:42:28 +0800
Subject: [PATCH] Resize ephyr screen automatically when parent window is resized.


Signed-off-by: Vic Lee <[email protected]>
---
 hw/kdrive/ephyr/ephyr.c |   49 +++++++++++++++++++++++++++++++++++++++++++++++
 hw/kdrive/ephyr/hostx.c |   37 +++++++++++++++++++++++++++-------
 hw/kdrive/ephyr/hostx.h |   10 ++++++++-
 3 files changed, 87 insertions(+), 9 deletions(-)

diff --git a/hw/kdrive/ephyr/ephyr.c b/hw/kdrive/ephyr/ephyr.c
index ab8459c..c11cc77 100644
--- a/hw/kdrive/ephyr/ephyr.c
+++ b/hw/kdrive/ephyr/ephyr.c
@@ -578,6 +578,8 @@ ephyrRandRSetConfig (ScreenPtr		pScreen,
   if (wasEnabled)
     KdEnableScreen (pScreen);
   
+  RRScreenSizeNotify(pScreen);
+
   return TRUE;
   
  bail4:
@@ -610,6 +612,45 @@ ephyrRandRInit (ScreenPtr pScreen)
   pScrPriv->rrSetConfig = ephyrRandRSetConfig;
   return TRUE;
 }
+
+static Bool
+ephyrResizeScreen (ScreenPtr		pScreen,
+		   int			newwidth,
+		   int			newheight)
+{
+  KdScreenPriv(pScreen);
+  KdScreenInfo	*screen    = pScreenPriv->screen;
+  RRScreenSize	size	   = {0};
+  Bool		ret;
+  int		t;
+
+  if (screen->randr & (RR_Rotate_90|RR_Rotate_270))
+    {
+      t = newwidth;
+      newwidth = newheight;
+      newheight = t;
+    }
+
+  if (newwidth == screen->width && newheight == screen->height)
+    {
+      return FALSE;
+    }
+
+  size.width = newwidth;
+  size.height = newheight;
+
+  ret = ephyrRandRSetConfig (pScreen, screen->randr, 0, &size);
+  if (ret)
+    {
+      RROutputPtr output;
+
+      output = RRFirstOutput(pScreen);
+      if (!output) return FALSE;
+      RROutputSetModes(output, NULL, 0, 0);
+    }
+
+  return ret;
+}
 #endif
 
 Bool
@@ -994,6 +1035,14 @@ ephyrPoll(void)
 	  break;
 #endif /* XF86DRI */
 
+#ifdef RANDR
+	case EPHYR_EV_CONFIGURE:
+	  ephyrResizeScreen (screenInfo.screens[ev.data.configure.screen],
+			     ev.data.configure.width,
+			     ev.data.configure.height);
+	  break;
+#endif /* RANDR */
+
 	default:
 	  break;
 	}
diff --git a/hw/kdrive/ephyr/hostx.c b/hw/kdrive/ephyr/hostx.c
index d289d73..7cf7557 100644
--- a/hw/kdrive/ephyr/hostx.c
+++ b/hw/kdrive/ephyr/hostx.c
@@ -335,7 +335,8 @@ hostx_init (void)
     |PointerMotionMask
     |KeyPressMask
     |KeyReleaseMask
-    |ExposureMask;
+    |ExposureMask
+    |StructureNotifyMask;
 
   EPHYR_DBG("mark");
 
@@ -716,13 +717,16 @@ hostx_screen_init (EphyrScreenInfo screen,
 
   XResizeWindow (HostX.dpy, host_screen->win, width, height);
 
-  /* Ask the WM to keep our size static */
-  size_hints = XAllocSizeHints();
-  size_hints->max_width = size_hints->min_width = width;
-  size_hints->max_height = size_hints->min_height = height;
-  size_hints->flags = PMinSize|PMaxSize;
-  XSetWMNormalHints(HostX.dpy, host_screen->win, size_hints);
-  XFree(size_hints);
+  if (host_screen->win_pre_existing == None)
+    {
+      /* Ask the WM to keep our size static */
+      size_hints = XAllocSizeHints();
+      size_hints->max_width = size_hints->min_width = width;
+      size_hints->max_height = size_hints->min_height = height;
+      size_hints->flags = PMinSize|PMaxSize;
+      XSetWMNormalHints(HostX.dpy, host_screen->win, size_hints);
+      XFree(size_hints);
+    }
 
   XMapWindow(HostX.dpy, host_screen->win);
 
@@ -1059,6 +1063,23 @@ hostx_get_event(EphyrHostXEvent *ev)
 	  ev->data.key_up.scancode = xev.xkey.keycode;
 	  return 1;
 
+	case ConfigureNotify:
+	  {
+	    struct EphyrHostScreen *host_screen =
+                host_screen_from_window (xev.xconfigure.window);
+
+	    if (host_screen && host_screen->win_pre_existing != None)
+	      {
+		ev->type = EPHYR_EV_CONFIGURE;
+		ev->data.configure.width = xev.xconfigure.width;
+		ev->data.configure.height = xev.xconfigure.height;
+		ev->data.configure.window = xev.xconfigure.window;
+		ev->data.configure.screen = host_screen->mynum;
+		return 1;
+	      }
+	  }
+	  return 0;
+
 	default:
 	  break;
 
diff --git a/hw/kdrive/ephyr/hostx.h b/hw/kdrive/ephyr/hostx.h
index c1b1958..43fa95f 100644
--- a/hw/kdrive/ephyr/hostx.h
+++ b/hw/kdrive/ephyr/hostx.h
@@ -48,7 +48,8 @@ typedef enum EphyrHostXEventType
   EPHYR_EV_MOUSE_RELEASE,
   EPHYR_EV_KEY_PRESS,
   EPHYR_EV_KEY_RELEASE,
-  EPHYR_EV_EXPOSE
+  EPHYR_EV_EXPOSE,
+  EPHYR_EV_CONFIGURE
 } 
 EphyrHostXEventType;
 
@@ -93,6 +94,13 @@ struct EphyrHostXEvent
       int window;
     } expose;
 
+    struct configure {
+      int width;
+      int height;
+      int screen;
+      int window;
+    } configure;
+
   } data;
 
   int key_state;
-- 
1.6.3.3

_______________________________________________
xorg-devel mailing list
[email protected]
http://lists.x.org/mailman/listinfo/xorg-devel

Reply via email to